Explorar el Código

+ merged Attila's changes for interfaces, not tested yet

florian hace 25 años
padre
commit
51527ba1c9

+ 9 - 3
compiler/cobjects.pas

@@ -281,7 +281,7 @@ interface
         procedure clear;
         procedure clear;
         procedure foreach(proc2call : Tnamedindexcallback);
         procedure foreach(proc2call : Tnamedindexcallback);
         procedure deleteindex(p:Pnamedindexobject);
         procedure deleteindex(p:Pnamedindexobject);
-        procedure delete(p:Pnamedindexobject);
+        procedure delete(var p:Pnamedindexobject);
         procedure insert(p:Pnamedindexobject);
         procedure insert(p:Pnamedindexobject);
         function  search(nr:longint):Pnamedindexobject;
         function  search(nr:longint):Pnamedindexobject;
       private
       private
@@ -1790,7 +1790,7 @@ end;
       end;
       end;
 
 
 
 
-    procedure tindexarray.delete(p:Pnamedindexobject);
+    procedure tindexarray.delete(var p:Pnamedindexobject);
       begin
       begin
         deleteindex(p);
         deleteindex(p);
         dispose(p,done);
         dispose(p,done);
@@ -1811,6 +1811,9 @@ end;
          count:=p^.indexnr;
          count:=p^.indexnr;
         if count>size then
         if count>size then
          grow(((count div growsize)+1)*growsize);
          grow(((count div growsize)+1)*growsize);
+        {$ifdef Delphi}
+        Assert(not assigned(data^[p^.indexnr]) or (p=data^[p^.indexnr]));
+        {$endif}
         data^[p^.indexnr]:=p;
         data^[p^.indexnr]:=p;
         { update linked list backward }
         { update linked list backward }
         i:=p^.indexnr;
         i:=p^.indexnr;
@@ -1843,7 +1846,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.17  2000-11-03 19:41:06  jonas
+  Revision 1.18  2000-11-04 14:25:19  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.17  2000/11/03 19:41:06  jonas
     * fixed bug in tdynamicarray.align (merged)
     * fixed bug in tdynamicarray.align (merged)
 
 
   Revision 1.16  2000/10/31 22:02:46  peter
   Revision 1.16  2000/10/31 22:02:46  peter

+ 19 - 3
compiler/errore.msg

@@ -295,6 +295,7 @@ scan_w_macro_support_turned_off=02057_W_Macro support has been turned off
 % A macro declaration has been found, but macro support is currently off,
 % A macro declaration has been found, but macro support is currently off,
 % so the declaration will be ignored. To turn macro support on compile with
 % so the declaration will be ignored. To turn macro support on compile with
 % -Sm on the commandline or add {$MACRO ON} in the source
 % -Sm on the commandline or add {$MACRO ON} in the source
+scan_e_invalid_interface_type=02058_E_Illegal interface type specified. Valids are COM, CORBA or DEFAULT.
 % \end{description}
 % \end{description}
 #
 #
 # Parser
 # Parser
@@ -624,8 +625,8 @@ parser_e_only_virtual_methods_abstract=03091_E_Only virtual methods can be abstr
 % virtual.
 % virtual.
 parser_f_unsupported_feature=03092_F_Use of unsupported feature!
 parser_f_unsupported_feature=03092_F_Use of unsupported feature!
 % You're trying to force the compiler into doing something it cannot do yet.
 % You're trying to force the compiler into doing something it cannot do yet.
-parser_e_mix_of_classes_and_objects=03093_E_The mix of CLASSES and OBJECTS isn't allowed
-% You cannot derive \var{objects} and \var{classes} intertwined . That is,
+parser_e_mix_of_classes_and_objects=03093_E_The mix of different kind of objects (class, object, interface, raw interface etc) isn't allowed
+% You cannot derive \var{objects}, \var{classes}, \var{cppclasses} and \var{interfaces} intertwined . E.g.
 % a class cannot have an object as parent and vice versa.
 % a class cannot have an object as parent and vice versa.
 parser_w_unknown_proc_directive_ignored=03094_W_Unknown procedure directive had to be ignored: "$1"
 parser_w_unknown_proc_directive_ignored=03094_W_Unknown procedure directive had to be ignored: "$1"
 % The procedure direcive you secified is unknown. Recognised procedure
 % The procedure direcive you secified is unknown. Recognised procedure
@@ -875,6 +876,20 @@ parser_e_no_export_with_index_for_target=03163_E_Can't export with index under $
 parser_e_no_export_of_variables_for_target=03164_E_Exporting of variables is not supported under $1
 parser_e_no_export_of_variables_for_target=03164_E_Exporting of variables is not supported under $1
 % Exporting of variables is not support on all targets. The only platform
 % Exporting of variables is not support on all targets. The only platform
 % currently supporting export of variables is Win32.
 % currently supporting export of variables is Win32.
+parser_e_improper_guid_syntax=03165_E_Improper GUID syntax
+parser_f_interface_cant_have_variables=03166_F_An interface can't have variables
+parser_f_interface_cant_have_constr_or_destr=03167_F_An interface can't have constructor or destructor
+parser_w_interface_mapping_notfound=03168_W_Procedure named $1 not found that is suitable for implementing the $2.$3
+parser_e_interface_id_expected=03169_E_interface identifier expected
+% This happens when the compiler scans a \var{class} declaration that contains
+% \var{interface} function name mapping code like this:
+% \begin{verbatim}
+% type
+%   TMyObject = class(TObject, IDispatch)
+%     function IUnknown.QueryInterface=MyQueryInterface;
+%     ....
+% \end{verbatim}
+% and the \var{interface} before the dot not listed in the inheritance list.
 % \end{description}
 % \end{description}
 #
 #
 # Type Checking
 # Type Checking
@@ -1016,6 +1031,7 @@ type_e_no_assign_to_const=04032_E_Can't assign values to const variable
 type_e_array_required=04033_E_Array type required
 type_e_array_required=04033_E_Array type required
 % If you are accessing a variable using an index '[<x>]' then
 % If you are accessing a variable using an index '[<x>]' then
 % the type must be an array. In FPC mode also a pointer is allowed.
 % the type must be an array. In FPC mode also a pointer is allowed.
+type_e_interface_type_expected=04034_E_interface type expected, but got "$1"
 % \end{description}
 % \end{description}
 #
 #
 # Symtable
 # Symtable
@@ -1914,4 +1930,4 @@ option_help_pages=11025_[
 
 
 #
 #
 # The End...
 # The End...
-#
+#

+ 88 - 1
compiler/globals.pas

@@ -148,6 +148,7 @@ interface
        initoptprocessor,
        initoptprocessor,
        initspecificoptprocessor : tprocessors;
        initspecificoptprocessor : tprocessors;
        initasmmode        : tasmmode;
        initasmmode        : tasmmode;
+       initinterfacetype  : tinterfacetypes;
      { current state values }
      { current state values }
        aktglobalswitches : tglobalswitches;
        aktglobalswitches : tglobalswitches;
        aktmoduleswitches : tmoduleswitches;
        aktmoduleswitches : tmoduleswitches;
@@ -165,6 +166,7 @@ interface
        aktoptprocessor,
        aktoptprocessor,
        aktspecificoptprocessor : tprocessors;
        aktspecificoptprocessor : tprocessors;
        aktasmmode        : tasmmode;
        aktasmmode        : tasmmode;
+       aktinterfacetype  : tinterfacetypes;
 
 
      { Memory sizes }
      { Memory sizes }
        heapsize,
        heapsize,
@@ -250,6 +252,9 @@ interface
     procedure InitGlobals;
     procedure InitGlobals;
     procedure DoneGlobals;
     procedure DoneGlobals;
 
 
+    function  string2guid(const s: string; var GUID: TGUID): boolean;
+    function  guid2string(const GUID: TGUID): string;
+
 
 
 implementation
 implementation
 
 
@@ -1043,6 +1048,84 @@ implementation
         SetCompileMode:=b;
         SetCompileMode:=b;
       end;
       end;
 
 
+    { '('D1:'00000000-'D2:'0000-'D3:'0000-'D4:'0000-000000000000)' }
+    function string2guid(const s: string; var GUID: TGUID): boolean;
+        function ishexstr(const hs: string): boolean;
+          var
+            i: integer;
+          begin
+            ishexstr:=false;
+            for i:=1 to Length(hs) do begin
+              if not (hs[i] in ['0'..'9','A'..'F','a'..'f']) then
+                exit;
+            end;
+            ishexstr:=true;
+          end;
+        function hexstr2longint(const hexs: string): longint;
+          var
+            i: integer;
+            rl: longint;
+          begin
+            rl:=0;
+            for i:=1 to length(hexs) do begin
+              rl:=rl shl 4;
+              case hexs[i] of
+                '0'..'9' : inc(rl,ord(hexs[i])-ord('0'));
+                'A'..'F' : inc(rl,ord(hexs[i])-ord('A')+10);
+                'a'..'f' : inc(rl,ord(hexs[i])-ord('a')+10);
+              end
+            end;
+            hexstr2longint:=rl;
+          end;
+      var
+        i: integer;
+      begin
+        if (Length(s)=38) and (s[1]='{') and (s[38]='}') and
+           (s[10]='-') and (s[15]='-') and (s[20]='-') and (s[25]='-') and
+           ishexstr(copy(s,2,8)) and ishexstr(copy(s,11,4)) and
+           ishexstr(copy(s,16,4)) and ishexstr(copy(s,21,4)) and
+           ishexstr(copy(s,26,12)) then begin
+          GUID.D1:=hexstr2longint(copy(s,2,8));
+          GUID.D2:=hexstr2longint(copy(s,11,4));
+          GUID.D3:=hexstr2longint(copy(s,16,4));
+          for i:=0 to 1 do
+            GUID.D4[i]:=hexstr2longint(copy(s,21+i*2,2));
+          for i:=2 to 7 do
+            GUID.D4[i]:=hexstr2longint(copy(s,22+i*2,2));
+          string2guid:=true;
+        end
+        else
+          string2guid:=false;
+      end;
+
+    function guid2string(const GUID: TGUID): string;
+        function long2hex(l, len: longint): string;
+          const
+            hextbl: array[0..15] of char = '0123456789ABCDEF';
+          var
+            rs: string;
+            i: integer;
+          begin
+            rs[0]:=chr(len);
+            for i:=len downto 1 do begin
+              rs[i]:=hextbl[l and $F];
+              l:=l shr 4;
+            end;
+            long2hex:=rs;
+          end;
+      begin
+        guid2string:=
+          '{'+long2hex(GUID.D1,8)+
+          '-'+long2hex(GUID.D2,4)+
+          '-'+long2hex(GUID.D3,4)+
+          '-'+long2hex(GUID.D4[0],2)+long2hex(GUID.D4[1],2)+
+          '-'+long2hex(GUID.D4[2],2)+long2hex(GUID.D4[3],2)+
+              long2hex(GUID.D4[4],2)+long2hex(GUID.D4[5],2)+
+              long2hex(GUID.D4[6],2)+long2hex(GUID.D4[7],2)+
+          '}';
+      end;
+
+
 
 
 {****************************************************************************
 {****************************************************************************
                                     Init
                                     Init
@@ -1160,6 +1243,7 @@ implementation
         initasmmode:=asmmode_m68k_mot;
         initasmmode:=asmmode_m68k_mot;
   {$endif m68k}
   {$endif m68k}
 {$endif i386}
 {$endif i386}
+        initinterfacetype:=it_interfacecom;
         initdefines.init;
         initdefines.init;
 
 
       { memory sizes, will be overriden by parameter or default for target
       { memory sizes, will be overriden by parameter or default for target
@@ -1186,7 +1270,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.17  2000-10-31 22:02:46  peter
+  Revision 1.18  2000-11-04 14:25:19  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.17  2000/10/31 22:02:46  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.16  2000/10/04 14:51:08  pierre
   Revision 1.16  2000/10/04 14:51:08  pierre

+ 23 - 2
compiler/globtype.pas

@@ -143,6 +143,12 @@ interface
          at_gui,at_cui
          at_gui,at_cui
        );
        );
 
 
+       { interface types }
+       tinterfacetypes = (
+         it_interfacecom,
+         it_interfacecorba
+       );
+
        { currently parsed block type }
        { currently parsed block type }
        tblock_type = (bt_none,
        tblock_type = (bt_none,
          bt_general,bt_type,bt_const,bt_except
          bt_general,bt_type,bt_const,bt_except
@@ -179,6 +185,18 @@ interface
                     (values:longint);
                     (values:longint);
        end;
        end;
 
 
+{$ifndef Delphi}
+  {$ifndef xFPC}
+    type
+      tguid = packed record
+        D1: LongWord;
+        D2: Word;
+        D3: Word;
+        D4: array[0..7] of Byte;
+      end;
+  {$endif}
+{$endif}
+
     const
     const
        { link options }
        { link options }
        link_none    = $0;
        link_none    = $0;
@@ -192,7 +210,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2000-09-24 15:06:16  peter
+  Revision 1.8  2000-11-04 14:25:19  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.7  2000/09/24 15:06:16  peter
     * use defines.inc
     * use defines.inc
 
 
   Revision 1.6  2000/09/21 11:30:49  jonas
   Revision 1.6  2000/09/21 11:30:49  jonas
@@ -211,4 +232,4 @@ end.
   Revision 1.2  2000/07/13 11:32:41  michael
   Revision 1.2  2000/07/13 11:32:41  michael
   + removed logs
   + removed logs
 
 
-}
+}

+ 50 - 24
compiler/hcgdata.pas

@@ -44,11 +44,8 @@ interface
     function gendmt(_class : pobjectdef) : pasmlabel;
     function gendmt(_class : pobjectdef) : pasmlabel;
 {$endif WITHDMT}
 {$endif WITHDMT}
 
 
-{ define INTERFACE_SUPPORT}
-
-{$ifdef INTERFACE_SUPPORT}
     function genintftable(_class: pobjectdef): pasmlabel;
     function genintftable(_class: pobjectdef): pasmlabel;
-{$endif INTERFACE_SUPPORT}
+    procedure writeinterfaceids(c : pobjectdef);
 
 
 implementation
 implementation
 
 
@@ -60,13 +57,11 @@ implementation
 {$endif}
 {$endif}
        cutils,cobjects,
        cutils,cobjects,
        globtype,globals,verbose,
        globtype,globals,verbose,
-       symconst,symtype,symsym,types,
+       symtable,symconst,symtype,symsym,types,
        hcodegen, systems,fmodule
        hcodegen, systems,fmodule
-{$ifdef INTERFACE_SUPPORT}
 {$ifdef i386}
 {$ifdef i386}
-       ,cg386ic
+       ,n386ic
 {$endif}
 {$endif}
-{$endif INTERFACE_SUPPORT}
        ;
        ;
 
 
 
 
@@ -550,7 +545,7 @@ implementation
                                           (po_virtualmethod in hp^.procoptions) then
                                           (po_virtualmethod in hp^.procoptions) then
                                          begin
                                          begin
                                             { in classes, we hide the old method }
                                             { in classes, we hide the old method }
-                                            if _c^.is_class then
+                                            if is_class(_c) then
                                               begin
                                               begin
                                                  { warn only if it is the first time,
                                                  { warn only if it is the first time,
                                                    we hide the method }
                                                    we hide the method }
@@ -586,7 +581,7 @@ implementation
                                        { (povirtualmethod is set! }
                                        { (povirtualmethod is set! }
 
 
                                        { class ? }
                                        { class ? }
-                                       if _c^.is_class and
+                                       if is_class(_c) and
                                           not(po_overridingmethod in hp^.procoptions) then
                                           not(po_overridingmethod in hp^.procoptions) then
                                          begin
                                          begin
                                             { warn only if it is the first time,
                                             { warn only if it is the first time,
@@ -602,8 +597,8 @@ implementation
                                        if not(is_equal(procdefcoll^.data^.rettype.def,hp^.rettype.def)) and
                                        if not(is_equal(procdefcoll^.data^.rettype.def,hp^.rettype.def)) and
                                          not((procdefcoll^.data^.rettype.def^.deftype=objectdef) and
                                          not((procdefcoll^.data^.rettype.def^.deftype=objectdef) and
                                            (hp^.rettype.def^.deftype=objectdef) and
                                            (hp^.rettype.def^.deftype=objectdef) and
-                                           (pobjectdef(procdefcoll^.data^.rettype.def)^.is_class) and
-                                           (pobjectdef(hp^.rettype.def)^.is_class) and
+                                           is_class(procdefcoll^.data^.rettype.def) and
+                                           is_class(hp^.rettype.def) and
                                            (pobjectdef(hp^.rettype.def)^.is_related(
                                            (pobjectdef(hp^.rettype.def)^.is_related(
                                                pobjectdef(procdefcoll^.data^.rettype.def)))) then
                                                pobjectdef(procdefcoll^.data^.rettype.def)))) then
                                          Message1(parser_e_overloaded_methodes_not_same_ret,hp^.fullprocname);
                                          Message1(parser_e_overloaded_methodes_not_same_ret,hp^.fullprocname);
@@ -758,15 +753,13 @@ implementation
          disposevmttree;
          disposevmttree;
       end;
       end;
 
 
-{$ifdef SUPPORT_INTERFACES}
-
     function  gintfgetvtbllabelname(_class: pobjectdef; intfindex: integer): string;
     function  gintfgetvtbllabelname(_class: pobjectdef; intfindex: integer): string;
       begin
       begin
         gintfgetvtbllabelname:='_$$_'+_class^.objname^+'_$$_'+
         gintfgetvtbllabelname:='_$$_'+_class^.objname^+'_$$_'+
           _class^.implementedinterfaces^.interfaces(intfindex)^.objname^+'_$$_VTBL';
           _class^.implementedinterfaces^.interfaces(intfindex)^.objname^+'_$$_VTBL';
       end;
       end;
 
 
-    procedure gintfcreatevtbl(_class: pobjectdef; intfindex: integer; rawdata: paasmoutput);
+    procedure gintfcreatevtbl(_class: pobjectdef; intfindex: integer; rawdata,rawcode: paasmoutput);
       var
       var
         implintf: pimplementedinterfaces;
         implintf: pimplementedinterfaces;
         curintf: pobjectdef;
         curintf: pobjectdef;
@@ -782,7 +775,7 @@ implementation
           begin
           begin
             tmps:=implintf^.implprocs(intfindex,i)^.mangledname+'_$$_'+curintf^.objname^;
             tmps:=implintf^.implprocs(intfindex,i)^.mangledname+'_$$_'+curintf^.objname^;
             { create wrapper code }
             { create wrapper code }
-            cgintfwrapper(implintf^.implprocs(intfindex,i),tmps,implintf^.ioffsets(intfindex)^);
+            cgintfwrapper(rawcode,implintf^.implprocs(intfindex,i),tmps,implintf^.ioffsets(intfindex)^);
             { create reference }
             { create reference }
             rawdata^.concat(new(pai_const_symbol,initname(tmps)));
             rawdata^.concat(new(pai_const_symbol,initname(tmps)));
           end;
           end;
@@ -830,6 +823,10 @@ implementation
         datasegment^.concat(new(pai_const_symbol,init(tmplabel)));
         datasegment^.concat(new(pai_const_symbol,init(tmplabel)));
       end;
       end;
 
 
+    type
+       tlongintarr = array[0..0] of longint;
+       plongintarr = ^tlongintarr;
+
     procedure gintfoptimizevtbls(_class: pobjectdef; var implvtbl: tlongintarr);
     procedure gintfoptimizevtbls(_class: pobjectdef; var implvtbl: tlongintarr);
       type
       type
         tcompintfentry = record
         tcompintfentry = record
@@ -911,7 +908,7 @@ implementation
 
 
     procedure gintfwritedata(_class: pobjectdef);
     procedure gintfwritedata(_class: pobjectdef);
       var
       var
-        rawdata: taasmoutput;
+        rawdata,rawcode: taasmoutput;
         impintfindexes: plongintarr;
         impintfindexes: plongintarr;
         max: longint;
         max: longint;
         i: longint;
         i: longint;
@@ -922,6 +919,7 @@ implementation
         gintfoptimizevtbls(_class,impintfindexes^);
         gintfoptimizevtbls(_class,impintfindexes^);
 
 
         rawdata.init;
         rawdata.init;
+        rawcode.init;
         datasegment^.concat(new(pai_const,init_16bit(max)));
         datasegment^.concat(new(pai_const,init_16bit(max)));
         { Two pass, one for allocation and vtbl creation }
         { Two pass, one for allocation and vtbl creation }
         for i:=1 to max do
         for i:=1 to max do
@@ -929,17 +927,17 @@ implementation
             if impintfindexes^[i]=i then { if implement itself }
             if impintfindexes^[i]=i then { if implement itself }
               begin
               begin
                 { allocate a pointer in the object memory }
                 { allocate a pointer in the object memory }
-                with _class^.symtable^ do
+                with pstoredsymtable(_class^.symtable)^ do
                   begin
                   begin
-                    if (alignment>=target_os.size_of_pointer) then
-                      datasize:=align(datasize,alignment)
+                    if (dataalignment>=target_os.size_of_pointer) then
+                      datasize:=align(datasize,dataalignment)
                     else
                     else
                       datasize:=align(datasize,target_os.size_of_pointer);
                       datasize:=align(datasize,target_os.size_of_pointer);
                     _class^.implementedinterfaces^.ioffsets(i)^:=datasize;
                     _class^.implementedinterfaces^.ioffsets(i)^:=datasize;
                     datasize:=datasize+target_os.size_of_pointer;
                     datasize:=datasize+target_os.size_of_pointer;
                   end;
                   end;
                 { write vtbl }
                 { write vtbl }
-                gintfcreatevtbl(_class,i,@rawdata);
+                gintfcreatevtbl(_class,i,@rawdata,@rawcode);
               end;
               end;
           end;
           end;
         { second pass: for fill interfacetable and remained ioffsets }
         { second pass: for fill interfacetable and remained ioffsets }
@@ -951,6 +949,10 @@ implementation
           end;
           end;
         datasegment^.insertlist(@rawdata);
         datasegment^.insertlist(@rawdata);
         rawdata.done;
         rawdata.done;
+        if (cs_create_smart in aktmoduleswitches) then
+          rawcode.insert(new(pai_cut,init));
+        codesegment^.insertlist(@rawcode);
+        rawcode.done;
         freemem(impintfindexes,(max+1)*sizeof(longint));
         freemem(impintfindexes,(max+1)*sizeof(longint));
       end;
       end;
 
 
@@ -964,7 +966,7 @@ implementation
         if assigned(sym) and (sym^.typ=procsym) and not (sp_private in sym^.symoptions) then
         if assigned(sym) and (sym^.typ=procsym) and not (sp_private in sym^.symoptions) then
           begin
           begin
             implprocdef:=sym^.definition;
             implprocdef:=sym^.definition;
-            while assigned(implprocdef) and not equal_paras(proc^.para,implprocdef^.para,false) and
+            while assigned(implprocdef) and not equal_paras(proc^.para,implprocdef^.para,cp_none) and
                   (proc^.proccalloptions<>implprocdef^.proccalloptions) do
                   (proc^.proccalloptions<>implprocdef^.proccalloptions) do
               implprocdef:=implprocdef^.nextoverloaded;
               implprocdef:=implprocdef^.nextoverloaded;
           end;
           end;
@@ -1035,12 +1037,36 @@ implementation
         genintftable:=intftable;
         genintftable:=intftable;
       end;
       end;
 
 
-{$endif SUPPORT_INTERFACES}
+  { Write interface identifiers to the data section }
+  procedure writeinterfaceids(c : pobjectdef);
+    var
+      i: longint;
+    begin
+      if c^.isiidguidvalid then
+        begin
+          if (cs_create_smart in aktmoduleswitches) then
+            datasegment^.concat(new(pai_cut,init));
+          datasegment^.concat(new(pai_symbol,initname_global(c^.vmt_mangledname+'$_IID',0)));
+          datasegment^.concat(new(pai_const,init_32bit(c^.iidguid.D1)));
+          datasegment^.concat(new(pai_const,init_16bit(c^.iidguid.D2)));
+          datasegment^.concat(new(pai_const,init_16bit(c^.iidguid.D3)));
+          for i:=Low(c^.iidguid.D4) to High(c^.iidguid.D4) do
+            datasegment^.concat(new(pai_const,init_8bit(c^.iidguid.D4[i])));
+        end;
+      if (cs_create_smart in aktmoduleswitches) then
+        datasegment^.concat(new(pai_cut,init));
+      datasegment^.concat(new(pai_symbol,initname_global(c^.vmt_mangledname+'$_IIDSTR',0)));
+      datasegment^.concat(new(pai_const,init_8bit(length(c^.iidstr^))));
+      datasegment^.concat(new(pai_string,init(c^.iidstr^)));
+    end;
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2000-11-01 23:04:37  peter
+  Revision 1.10  2000-11-04 14:25:19  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.9  2000/11/01 23:04:37  peter
     * tprocdef.fullprocname added for better casesensitve writing of
     * tprocdef.fullprocname added for better casesensitve writing of
       procedures
       procedures
 
 

+ 15 - 14
compiler/htypechk.pas

@@ -187,16 +187,15 @@ implementation
                  is_chararray(ld)))
                  is_chararray(ld)))
            ) or
            ) or
            { <> and = are defined for classes }
            { <> and = are defined for classes }
-           ((ld^.deftype=objectdef) and
-            (not(pobjectdef(ld)^.is_class) or
-             not(treetyp in [equaln,unequaln])
-            )
+           (
+            (ld^.deftype=objectdef) and
+            not((treetyp in [equaln,unequaln]) and (is_class(ld) or is_interface(ld)))
            ) or
            ) or
-           ((rd^.deftype=objectdef) and
-            (not(pobjectdef(rd)^.is_class) or
-             not(treetyp in [equaln,unequaln])
-            )
-             or
+           (
+            (rd^.deftype=objectdef) and
+            not((treetyp in [equaln,unequaln]) and (is_class(rd) or is_interface(rd)))
+           )
+           or
            { allow other operators that + on strings }
            { allow other operators that + on strings }
            (
            (
             (is_char(rd) or
             (is_char(rd) or
@@ -213,8 +212,7 @@ implementation
                  (is_integer(rd) or (rd^.deftype=pointerdef)) and
                  (is_integer(rd) or (rd^.deftype=pointerdef)) and
                  (treetyp=subn)
                  (treetyp=subn)
                 )
                 )
-            )
-           );
+            );
       end;
       end;
 
 
 
 
@@ -593,7 +591,7 @@ implementation
                    pointerdef :
                    pointerdef :
                      gotpointer:=true;
                      gotpointer:=true;
                    objectdef :
                    objectdef :
-                     gotclass:=pobjectdef(hp.resulttype)^.is_class;
+                     gotclass:=is_class_or_interface(hp.resulttype);
                    classrefdef :
                    classrefdef :
                      gotclass:=true;
                      gotclass:=true;
                    arraydef :
                    arraydef :
@@ -646,7 +644,7 @@ implementation
                    pointerdef :
                    pointerdef :
                      gotpointer:=true;
                      gotpointer:=true;
                    objectdef :
                    objectdef :
-                     gotclass:=pobjectdef(hp.resulttype)^.is_class;
+                     gotclass:=is_class_or_interface(hp.resulttype);
                    recorddef, { handle record like class it needs a subscription }
                    recorddef, { handle record like class it needs a subscription }
                    classrefdef :
                    classrefdef :
                      gotclass:=true;
                      gotclass:=true;
@@ -889,7 +887,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.13  2000-10-31 22:02:47  peter
+  Revision 1.14  2000-11-04 14:25:19  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.13  2000/10/31 22:02:47  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.12  2000/10/14 10:14:47  peter
   Revision 1.12  2000/10/14 10:14:47  peter

+ 198 - 79
compiler/i386/cgai386.pas

@@ -111,6 +111,9 @@ interface
     procedure emit_push_mem(const ref : treference);
     procedure emit_push_mem(const ref : treference);
     procedure emitpushreferenceaddr(const ref : treference);
     procedure emitpushreferenceaddr(const ref : treference);
 
 
+    procedure incrcomintfref(t: pdef; const ref: treference);
+    procedure decrcomintfref(t: pdef; const ref: treference);
+
     procedure floatload(t : tfloattype;const ref : treference);
     procedure floatload(t : tfloattype;const ref : treference);
     procedure floatstore(t : tfloattype;const ref : treference);
     procedure floatstore(t : tfloattype;const ref : treference);
     procedure floatloadops(t : tfloattype;var op : tasmop;var s : topsize);
     procedure floatloadops(t : tfloattype;var op : tasmop;var s : topsize);
@@ -970,6 +973,41 @@ implementation
                            Emit String Functions
                            Emit String Functions
 *****************************************************************************}
 *****************************************************************************}
 
 
+    procedure incrcomintfref(t: pdef; const ref: treference);
+
+      var
+         pushedregs : tpushed;
+
+      begin
+         pushusedregisters(pushedregs,$ff);
+         emitpushreferenceaddr(ref);
+         if is_interfacecom(t) then
+           begin
+              emitcall('FPC_INTF_INCR_REF');
+           end
+         else internalerror(1859);
+         popusedregisters(pushedregs);
+      end;
+
+
+    procedure decrcomintfref(t: pdef; const ref: treference);
+
+      var
+         pushedregs : tpushed;
+
+      begin
+         pushusedregisters(pushedregs,$ff);
+         emitpushreferenceaddr(ref);
+         if is_interfacecom(t) then
+           begin
+              emitcall('FPC_INTF_DECR_REF');
+           end
+         else internalerror(1859);
+         popusedregisters(pushedregs);
+      end;
+
+
+
     procedure copyshortstring(const dref,sref : treference;len : byte;
     procedure copyshortstring(const dref,sref : treference;len : byte;
                 loadref, del_sref: boolean);
                 loadref, del_sref: boolean);
       begin
       begin
@@ -1041,7 +1079,6 @@ implementation
          popusedregisters(pushedregs);
          popusedregisters(pushedregs);
       end;
       end;
 
 
-
 {*****************************************************************************
 {*****************************************************************************
                            Emit Push Functions
                            Emit Push Functions
 *****************************************************************************}
 *****************************************************************************}
@@ -1585,7 +1622,8 @@ implementation
 
 
       begin
       begin
          if is_ansistring(t) or
          if is_ansistring(t) or
-           is_widestring(t) then
+           is_widestring(t) or
+           is_interfacecom(t) then
            begin
            begin
               emit_const_ref(A_MOV,S_L,0,
               emit_const_ref(A_MOV,S_L,0,
                 newreference(ref));
                 newreference(ref));
@@ -1618,6 +1656,10 @@ implementation
            begin
            begin
               decrstringref(t,ref);
               decrstringref(t,ref);
            end
            end
+         else if is_interfacecom(t) then
+           begin
+              decrcomintfref(t,ref);
+           end
          else
          else
            begin
            begin
               reset_reference(r);
               reset_reference(r);
@@ -1642,8 +1684,7 @@ implementation
     begin
     begin
        if (psym(p)^.typ=varsym) and
        if (psym(p)^.typ=varsym) and
           assigned(pvarsym(p)^.vartype.def) and
           assigned(pvarsym(p)^.vartype.def) and
-          not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-            pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
+          not(is_class(pvarsym(p)^.vartype.def)) and
           pvarsym(p)^.vartype.def^.needs_inittable then
           pvarsym(p)^.vartype.def^.needs_inittable then
          begin
          begin
             if assigned(procinfo) then
             if assigned(procinfo) then
@@ -1662,37 +1703,103 @@ implementation
          end;
          end;
     end;
     end;
 
 
-  { generates the code for incrementing the reference count of parameters }
-  procedure incr_data(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
+  { generates the code for incrementing the reference count of parameters and
+    initialize out parameters }
+  procedure init_paras(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
 
 
     var
     var
-       hr : treference;
+       hrv : treference;
+       hr: treference;
 
 
     begin
     begin
        if (psym(p)^.typ=varsym) and
        if (psym(p)^.typ=varsym) and
-          not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-            pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-          pvarsym(p)^.vartype.def^.needs_inittable and
-          (not assigned(pvarsym(p)^.localvarsym)) and
-          ((pvarsym(p)^.varspez=vs_value) {or
-           (pvarsym(p)^.varspez=vs_const) and
-           not(dont_copy_const_param(pvarsym(p)^.definition))}) then
+          not is_class(pvarsym(p)^.vartype.def) and
+          pvarsym(p)^.vartype.def^.needs_inittable then
          begin
          begin
-            procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-            reset_reference(hr);
-            hr.symbol:=pstoreddef(pvarsym(p)^.vartype.def)^.get_inittable_label;
-            emitpushreferenceaddr(hr);
-            reset_reference(hr);
-            hr.base:=procinfo^.framepointer;
-            hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
+           if (pvarsym(p)^.varspez=vs_value) then
+             begin
+               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
 
 
-            emitpushreferenceaddr(hr);
-            reset_reference(hr);
+               reset_reference(hrv);
+               hrv.base:=procinfo^.framepointer;
+               hrv.offset:=pvarsym(p)^.address+procinfo^.para_offset;
 
 
-            emitcall('FPC_ADDREF');
+               if is_ansistring(pvarsym(p)^.vartype.def) or
+                  is_widestring(pvarsym(p)^.vartype.def) then
+                 begin
+                   incrstringref(pvarsym(p)^.vartype.def,hrv)
+                 end
+               else if is_interfacecom(pvarsym(p)^.vartype.def) then
+                 begin
+                   incrcomintfref(pvarsym(p)^.vartype.def,hrv)
+                 end
+               else
+                 begin
+                   reset_reference(hr);
+                   hr.symbol:=pstoreddef(pvarsym(p)^.vartype.def)^.get_inittable_label;
+                   emitpushreferenceaddr(hr);
+                   emitpushreferenceaddr(hrv);
+                   emitcall('FPC_ADDREF');
+                 end;
+             end
+           else if (pvarsym(p)^.varspez=vs_out) then
+             begin
+               reset_reference(hrv);
+               hrv.base:=procinfo^.framepointer;
+               hrv.offset:=pvarsym(p)^.address+procinfo^.para_offset;
+               {$ifndef noAllocEdi}
+               getexplicitregister32(R_EDI);
+               {$endif noAllocEdi}
+               exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,newreference(hrv),R_EDI)));
+               reset_reference(hr);
+               hr.base:=R_EDI;
+               initialize(pvarsym(p)^.vartype.def,hr,false);
+             end;
          end;
          end;
     end;
     end;
 
 
+  { generates the code for decrementing the reference count of parameters }
+  procedure final_paras(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
+
+    var
+       hrv : treference;
+       hr: treference;
+
+    begin
+       if (psym(p)^.typ=varsym) and
+          not is_class(pvarsym(p)^.vartype.def) and
+          pvarsym(p)^.vartype.def^.needs_inittable then
+         begin
+           if (pvarsym(p)^.varspez=vs_value) then
+             begin
+               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+
+               reset_reference(hrv);
+               hrv.base:=procinfo^.framepointer;
+               hrv.offset:=pvarsym(p)^.address+procinfo^.para_offset;
+
+               if is_ansistring(pvarsym(p)^.vartype.def) or
+                  is_widestring(pvarsym(p)^.vartype.def) then
+                 begin
+                   decrstringref(pvarsym(p)^.vartype.def,hrv)
+                 end
+               else if is_interfacecom(pvarsym(p)^.vartype.def) then
+                 begin
+                   decrcomintfref(pvarsym(p)^.vartype.def,hrv)
+                 end
+               else
+                 begin
+                   reset_reference(hr);
+                   hr.symbol:=pstoreddef(pvarsym(p)^.vartype.def)^.get_inittable_label;
+                   emitpushreferenceaddr(hr);
+                   emitpushreferenceaddr(hrv);
+                   emitcall('FPC_DECREF');
+                 end;
+             end;
+         end;
+    end;
+
+
   { generates the code for finalisation of local data }
   { generates the code for finalisation of local data }
   procedure finalize_data(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
   procedure finalize_data(p : pnamedindexobject);{$ifndef FPC}far;{$endif}
 
 
@@ -1702,15 +1809,9 @@ implementation
     begin
     begin
        if (psym(p)^.typ=varsym) and
        if (psym(p)^.typ=varsym) and
           assigned(pvarsym(p)^.vartype.def) and
           assigned(pvarsym(p)^.vartype.def) and
-          not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-          pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
-          (not assigned(pvarsym(p)^.localvarsym)) and
+          not(is_class(pvarsym(p)^.vartype.def)) and
           pvarsym(p)^.vartype.def^.needs_inittable then
           pvarsym(p)^.vartype.def^.needs_inittable then
          begin
          begin
-            { not all kind of parameters need to be finalized  }
-            if (psym(p)^.owner^.symtabletype=parasymtable) and
-              (pvarsym(p)^.varspez in [vs_out,vs_var,vs_const]) then
-              exit;
             if assigned(procinfo) then
             if assigned(procinfo) then
               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
             reset_reference(hr);
             reset_reference(hr);
@@ -1720,11 +1821,6 @@ implementation
                     hr.base:=procinfo^.framepointer;
                     hr.base:=procinfo^.framepointer;
                     hr.offset:=-pvarsym(p)^.address+pvarsym(p)^.owner^.address_fixup;
                     hr.offset:=-pvarsym(p)^.address+pvarsym(p)^.owner^.address_fixup;
                  end;
                  end;
-               parasymtable,inlineparasymtable:
-                 begin
-                    hr.base:=procinfo^.framepointer;
-                    hr.offset:=pvarsym(p)^.address+procinfo^.para_offset;
-                 end;
                else
                else
                  hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
                  hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
             end;
             end;
@@ -1920,7 +2016,7 @@ implementation
         end;
         end;
     end;
     end;
 
 
-  procedure inittempansistrings;
+  procedure inittempvariables;
 
 
     var
     var
        hp : ptemprecord;
        hp : ptemprecord;
@@ -1930,20 +2026,20 @@ implementation
        hp:=templist;
        hp:=templist;
        while assigned(hp) do
        while assigned(hp) do
          begin
          begin
-           if hp^.temptype in [tt_ansistring,tt_freeansistring] then
-            begin
-              procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-              new(r);
-              reset_reference(r^);
-              r^.base:=procinfo^.framepointer;
-              r^.offset:=hp^.pos;
-              emit_const_ref(A_MOV,S_L,0,r);
-            end;
-            hp:=hp^.next;
+           if hp^.temptype in [tt_ansistring,tt_freeansistring,tt_interfacecom] then
+             begin
+               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+               new(r);
+               reset_reference(r^);
+               r^.base:=procinfo^.framepointer;
+               r^.offset:=hp^.pos;
+               emit_const_ref(A_MOV,S_L,0,r);
+             end;
+           hp:=hp^.next;
          end;
          end;
    end;
    end;
 
 
-  procedure finalizetempansistrings;
+  procedure finalizetempvariables;
 
 
     var
     var
        hp : ptemprecord;
        hp : ptemprecord;
@@ -1954,12 +2050,21 @@ implementation
          begin
          begin
             if hp^.temptype in [tt_ansistring,tt_freeansistring] then
             if hp^.temptype in [tt_ansistring,tt_freeansistring] then
               begin
               begin
-                 procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
-                 reset_reference(hr);
-                 hr.base:=procinfo^.framepointer;
-                 hr.offset:=hp^.pos;
-                 emitpushreferenceaddr(hr);
-                 emitcall('FPC_ANSISTR_DECR_REF');
+                procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+                reset_reference(hr);
+                hr.base:=procinfo^.framepointer;
+                hr.offset:=hp^.pos;
+                emitpushreferenceaddr(hr);
+                emitcall('FPC_ANSISTR_DECR_REF');
+              end
+            else if hp^.temptype=tt_interfacecom then
+              begin
+                procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
+                reset_reference(hr);
+                hr.base:=procinfo^.framepointer;
+                hr.offset:=hp^.pos;
+                emitpushreferenceaddr(hr);
+                emitcall('FPC_INTF_DECR_REF');
               end;
               end;
             hp:=hp^.next;
             hp:=hp^.next;
          end;
          end;
@@ -2038,19 +2143,21 @@ implementation
       { a constructor needs a help procedure }
       { a constructor needs a help procedure }
       if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
       if (aktprocsym^.definition^.proctypeoption=potype_constructor) then
         begin
         begin
-          if procinfo^._class^.is_class then
+          if is_class(procinfo^._class) then
             begin
             begin
               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
               procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
               exprasmlist^.insert(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,faillabel)));
               exprasmlist^.insert(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,faillabel)));
               emitinsertcall('FPC_NEW_CLASS');
               emitinsertcall('FPC_NEW_CLASS');
             end
             end
-          else
+          else if is_object(procinfo^._class) then
             begin
             begin
               exprasmlist^.insert(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,faillabel)));
               exprasmlist^.insert(new(paicpu,op_cond_sym(A_Jcc,C_Z,S_NO,faillabel)));
               emitinsertcall('FPC_HELP_CONSTRUCTOR');
               emitinsertcall('FPC_HELP_CONSTRUCTOR');
               getexplicitregister32(R_EDI);
               getexplicitregister32(R_EDI);
               exprasmlist^.insert(new(paicpu,op_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI)));
               exprasmlist^.insert(new(paicpu,op_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI)));
-            end;
+            end
+          else
+            Internalerror(200006161);
         end;
         end;
 
 
       { don't load ESI, does the caller }
       { don't load ESI, does the caller }
@@ -2058,7 +2165,7 @@ implementation
       { that can be called from a foreach }
       { that can be called from a foreach }
       { of another object than self !! PM }
       { of another object than self !! PM }
 
 
-         if assigned(procinfo^._class) and
+         if assigned(procinfo^._class) and  { !!!!! shouldn't we load ESI always? }
             (lexlevel>normal_function_level) then
             (lexlevel>normal_function_level) then
            maybe_loadesi;
            maybe_loadesi;
 
 
@@ -2090,8 +2197,7 @@ implementation
         end;
         end;
 
 
       { omit stack frame ? }
       { omit stack frame ? }
-      if not inlined then
-      if procinfo^.framepointer=stack_pointer then
+      if (not inlined) and (procinfo^.framepointer=stack_pointer) then
           begin
           begin
               CGMessage(cg_d_stackframe_omited);
               CGMessage(cg_d_stackframe_omited);
               nostackframe:=true;
               nostackframe:=true;
@@ -2204,8 +2310,7 @@ implementation
       { initialize return value }
       { initialize return value }
       if (procinfo^.returntype.def<>pdef(voiddef)) and
       if (procinfo^.returntype.def<>pdef(voiddef)) and
         (procinfo^.returntype.def^.needs_inittable) and
         (procinfo^.returntype.def^.needs_inittable) and
-        ((procinfo^.returntype.def^.deftype<>objectdef) or
-        not(pobjectdef(procinfo^.returntype.def)^.is_class)) then
+        not(is_class(procinfo^.returntype.def)) then
         begin
         begin
            procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
            procinfo^.flags:=procinfo^.flags or pi_needs_implicit_finally;
            reset_reference(r);
            reset_reference(r);
@@ -2228,7 +2333,7 @@ implementation
          else
          else
            aktprocsym^.definition^.localst^.foreach({$ifndef TP}@{$endif}initialize_data);
            aktprocsym^.definition^.localst^.foreach({$ifndef TP}@{$endif}initialize_data);
       end;
       end;
-
+      {
       { generate copies of call by value parameters }
       { generate copies of call by value parameters }
       if not(po_assembler in aktprocsym^.definition^.procoptions) and
       if not(po_assembler in aktprocsym^.definition^.procoptions) and
          (([pocall_cdecl,pocall_cppdecl]*aktprocsym^.definition^.proccalloptions)=[]) then
          (([pocall_cdecl,pocall_cppdecl]*aktprocsym^.definition^.proccalloptions)=[]) then
@@ -2236,11 +2341,11 @@ implementation
 
 
       { add a reference to all call by value/const parameters }
       { add a reference to all call by value/const parameters }
       aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}incr_data);
       aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}incr_data);
-
+      }
       { initialisizes temp. ansi/wide string data }
       { initialisizes temp. ansi/wide string data }
-      inittempansistrings;
+      inittempvariables;
 
 
-      { do we need an exception frame because of ansi/widestrings ? }
+      { do we need an exception frame because of ansi/widestrings/interfaces ? }
       if not inlined and
       if not inlined and
          ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
          ((procinfo^.flags and pi_needs_implicit_finally)<>0) and
       { but it's useless in init/final code of units }
       { but it's useless in init/final code of units }
@@ -2406,11 +2511,11 @@ implementation
       if (aktprocsym^.definition^.proctypeoption=potype_destructor) and
       if (aktprocsym^.definition^.proctypeoption=potype_destructor) and
          assigned(procinfo^._class) then
          assigned(procinfo^._class) then
         begin
         begin
-          if procinfo^._class^.is_class then
+          if is_class(procinfo^._class) then
             begin
             begin
               emitinsertcall('FPC_DISPOSE_CLASS');
               emitinsertcall('FPC_DISPOSE_CLASS');
             end
             end
-          else
+          else if is_object(procinfo^._class) then
             begin
             begin
               emitinsertcall('FPC_HELP_DESTRUCTOR');
               emitinsertcall('FPC_HELP_DESTRUCTOR');
               getexplicitregister32(R_EDI);
               getexplicitregister32(R_EDI);
@@ -2432,11 +2537,15 @@ implementation
                    hr.offset:=8;
                    hr.offset:=8;
                    exprasmlist^.insert(new(paicpu,op_const_ref(A_CMP,S_L,0,newreference(hr))));
                    exprasmlist^.insert(new(paicpu,op_const_ref(A_CMP,S_L,0,newreference(hr))));
                 end;
                 end;
+            end
+          else
+            begin
+              Internalerror(200006161);
             end;
             end;
         end;
         end;
 
 
       { finalize temporary data }
       { finalize temporary data }
-      finalizetempansistrings;
+      finalizetempvariables;
 
 
       { finalize local data like ansistrings}
       { finalize local data like ansistrings}
       case aktprocsym^.definition^.proctypeoption of
       case aktprocsym^.definition^.proctypeoption of
@@ -2455,7 +2564,7 @@ implementation
 
 
       { finalize paras data }
       { finalize paras data }
       if assigned(aktprocsym^.definition^.parast) then
       if assigned(aktprocsym^.definition^.parast) then
-        aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}finalize_data);
+        aktprocsym^.definition^.parast^.foreach({$ifndef TP}@{$endif}final_paras);
 
 
       { do we need to handle exceptions because of ansi/widestrings ? }
       { do we need to handle exceptions because of ansi/widestrings ? }
       if not inlined and
       if not inlined and
@@ -2486,15 +2595,19 @@ implementation
                           emit_const_ref(A_CMP,S_L,0,new_reference(procinfo^.framepointer,
                           emit_const_ref(A_CMP,S_L,0,new_reference(procinfo^.framepointer,
                             procinfo^.selfpointer_offset));
                             procinfo^.selfpointer_offset));
                           emitjmp(C_E,nodestroycall);
                           emitjmp(C_E,nodestroycall);
-                          if procinfo^._class^.is_class then
+                          if is_class(procinfo^._class) then
                             begin
                             begin
                                emit_const(A_PUSH,S_L,1);
                                emit_const(A_PUSH,S_L,1);
                                emit_reg(A_PUSH,S_L,R_ESI);
                                emit_reg(A_PUSH,S_L,R_ESI);
                             end
                             end
-                          else
+                          else if is_object(procinfo^._class) then
                             begin
                             begin
                                emit_reg(A_PUSH,S_L,R_ESI);
                                emit_reg(A_PUSH,S_L,R_ESI);
                                emit_sym(A_PUSH,S_L,newasmsymbol(procinfo^._class^.vmt_mangledname));
                                emit_sym(A_PUSH,S_L,newasmsymbol(procinfo^._class^.vmt_mangledname));
+                            end
+                          else
+                            begin
+                              Internalerror(200006161);
                             end;
                             end;
                           if (po_virtualmethod in pd^.procoptions) then
                           if (po_virtualmethod in pd^.procoptions) then
                             begin
                             begin
@@ -2517,7 +2630,7 @@ implementation
            if (procinfo^.returntype.def<>pdef(voiddef)) and
            if (procinfo^.returntype.def<>pdef(voiddef)) and
              (procinfo^.returntype.def^.needs_inittable) and
              (procinfo^.returntype.def^.needs_inittable) and
              ((procinfo^.returntype.def^.deftype<>objectdef) or
              ((procinfo^.returntype.def^.deftype<>objectdef) or
-             not(pobjectdef(procinfo^.returntype.def)^.is_class)) then
+              not is_class(procinfo^.returntype.def)) then
              begin
              begin
                 reset_reference(hr);
                 reset_reference(hr);
                 hr.offset:=procinfo^.return_offset;
                 hr.offset:=procinfo^.return_offset;
@@ -2550,19 +2663,22 @@ implementation
                   getlabel(okexitlabel);
                   getlabel(okexitlabel);
                   emitjmp(C_NONE,okexitlabel);
                   emitjmp(C_NONE,okexitlabel);
                   emitlab(faillabel);
                   emitlab(faillabel);
-                  if procinfo^._class^.is_class then
+                  if is_class(procinfo^._class) then
                     begin
                     begin
                       emit_ref_reg(A_MOV,S_L,new_reference(procinfo^.framepointer,8),R_ESI);
                       emit_ref_reg(A_MOV,S_L,new_reference(procinfo^.framepointer,8),R_ESI);
                       emitcall('FPC_HELP_FAIL_CLASS');
                       emitcall('FPC_HELP_FAIL_CLASS');
                     end
                     end
-                  else
+                  else if is_object(procinfo^._class) then
                     begin
                     begin
                       emit_ref_reg(A_MOV,S_L,new_reference(procinfo^.framepointer,12),R_ESI);
                       emit_ref_reg(A_MOV,S_L,new_reference(procinfo^.framepointer,12),R_ESI);
                        getexplicitregister32(R_EDI);
                        getexplicitregister32(R_EDI);
                       emit_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI);
                       emit_const_reg(A_MOV,S_L,procinfo^._class^.vmt_offset,R_EDI);
                       emitcall('FPC_HELP_FAIL');
                       emitcall('FPC_HELP_FAIL');
                       ungetregister32(R_EDI);
                       ungetregister32(R_EDI);
-                    end;
+                    end
+                  else
+                    Internalerror(200006161);
+
                   emitlab(okexitlabel);
                   emitlab(okexitlabel);
 
 
                   exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
                   exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
@@ -2675,7 +2791,7 @@ implementation
                 if (not assigned(procinfo^.parent) or
                 if (not assigned(procinfo^.parent) or
                    not assigned(procinfo^.parent^._class)) then
                    not assigned(procinfo^.parent^._class)) then
                   begin
                   begin
-                    if not  procinfo^._class^.is_class then
+                    if not(is_class(procinfo^._class)) then
                       st:='v'
                       st:='v'
                     else
                     else
                       st:='p';
                       st:='p';
@@ -2685,7 +2801,7 @@ implementation
                   end
                   end
                 else
                 else
                   begin
                   begin
-                    if not  procinfo^._class^.is_class then
+                    if not is_class(procinfo^._class) then
                       st:='*'
                       st:='*'
                     else
                     else
                       st:='';
                       st:='';
@@ -2816,7 +2932,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.6  2000-10-31 22:02:55  peter
+  Revision 1.7  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.6  2000/10/31 22:02:55  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.5  2000/10/24 22:23:04  peter
   Revision 1.5  2000/10/24 22:23:04  peter

+ 5 - 6
compiler/i386/n386add.pas

@@ -923,11 +923,7 @@ interface
 
 
                  (right.resulttype^.deftype=pointerdef) or
                  (right.resulttype^.deftype=pointerdef) or
 
 
-                 ((right.resulttype^.deftype=objectdef) and
-                  pobjectdef(right.resulttype)^.is_class and
-                 (left.resulttype^.deftype=objectdef) and
-                  pobjectdef(left.resulttype)^.is_class
-                 ) or
+                 (is_class(right.resulttype) and is_class(left.resulttype)) or
 
 
                  (left.resulttype^.deftype=classrefdef) or
                  (left.resulttype^.deftype=classrefdef) or
 
 
@@ -2292,7 +2288,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:56  peter
+  Revision 1.3  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:56  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/15 09:33:31  peter
   Revision 1.1  2000/10/15 09:33:31  peter

+ 5 - 2
compiler/i386/n386bas.pas

@@ -143,7 +143,7 @@ unit n386bas;
          else
          else
            begin
            begin
              { if the routine is an inline routine, then we must hold a copy
              { if the routine is an inline routine, then we must hold a copy
-               becuase it can be necessary for inlining later }
+               because it can be necessary for inlining later }
              if (pocall_inline in aktprocsym^.definition^.proccalloptions) then
              if (pocall_inline in aktprocsym^.definition^.proccalloptions) then
                exprasmlist^.concatlistcopy(p_asm)
                exprasmlist^.concatlistcopy(p_asm)
              else
              else
@@ -204,7 +204,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:56  peter
+  Revision 1.3  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:56  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/15 09:33:31  peter
   Revision 1.1  2000/10/15 09:33:31  peter

+ 28 - 63
compiler/i386/n386cal.pas

@@ -90,44 +90,6 @@ implementation
              end;
              end;
         end;
         end;
 
 
-      procedure prepareout(const r : treference);
-
-        var
-           hr : treference;
-           pushed : tpushed;
-
-        begin
-           { out parameters needs to be finalized }
-           if (defcoll^.paratype.def^.needs_inittable) then
-             begin
-                reset_reference(hr);
-                hr.symbol:=pstoreddef(defcoll^.paratype.def)^.get_inittable_label;
-                emitpushreferenceaddr(hr);
-                emitpushreferenceaddr(r);
-                emitcall('FPC_FINALIZE');
-             end
-           else
-           { or at least it zeroed out }
-             begin
-                case defcoll^.paratype.def^.size of
-                   1:
-                     emit_const_ref(A_MOV,S_B,0,newreference(r));
-                   2:
-                     emit_const_ref(A_MOV,S_W,0,newreference(r));
-                   4:
-                     emit_const_ref(A_MOV,S_L,0,newreference(r));
-                   else
-                     begin
-                        pushusedregisters(pushed,$ff);
-                        emit_const(A_PUSH,S_W,0);
-                        push_int(defcoll^.paratype.def^.size);
-                        emitpushreferenceaddr(r);
-                        emitcall('FPC_FILLCHAR');
-                        popusedregisters(pushed);
-                     end
-                end;
-             end;
-        end;
       var
       var
          otlabel,oflabel : pasmlabel;
          otlabel,oflabel : pasmlabel;
          { temporary variables: }
          { temporary variables: }
@@ -200,6 +162,11 @@ implementation
               if (left.location.loc<>LOC_REFERENCE) then
               if (left.location.loc<>LOC_REFERENCE) then
                 CGMessage(cg_e_var_must_be_reference);
                 CGMessage(cg_e_var_must_be_reference);
               maybe_push_high;
               maybe_push_high;
+              if (defcoll^.paratyp=vs_out) and
+                 assigned(defcoll^.paratype.def) and
+                 not is_class(defcoll^.paratype.def) and
+                 defcoll^.paratype.def^.needs_inittable then
+                finalize(defcoll^.paratype.def,left.location.reference,false);
               inc(pushedparasize,4);
               inc(pushedparasize,4);
               if inlined then
               if inlined then
                 begin
                 begin
@@ -212,8 +179,6 @@ implementation
                 end
                 end
               else
               else
                 emitpushreferenceaddr(left.location.reference);
                 emitpushreferenceaddr(left.location.reference);
-              if defcoll^.paratyp=vs_out then
-                prepareout(left.location.reference);
               del_reference(left.location.reference);
               del_reference(left.location.reference);
            end
            end
          else
          else
@@ -562,7 +527,7 @@ implementation
                    r^:=twithnode(pwithsymtable(symtableproc)^.withnode).withreference^;
                    r^:=twithnode(pwithsymtable(symtableproc)^.withnode).withreference^;
                    if ((not(nf_islocal in twithnode(pwithsymtable(symtableproc)^.withnode).flags)) and
                    if ((not(nf_islocal in twithnode(pwithsymtable(symtableproc)^.withnode).flags)) and
                        (not pwithsymtable(symtableproc)^.direct_with)) or
                        (not pwithsymtable(symtableproc)^.direct_with)) or
-                      pobjectdef(methodpointer.resulttype)^.is_class then
+                      is_class_or_interface(methodpointer.resulttype) then
                      emit_ref_reg(A_MOV,S_L,r,R_ESI)
                      emit_ref_reg(A_MOV,S_L,r,R_ESI)
                    else
                    else
                      emit_ref_reg(A_LEA,S_L,r,R_ESI);
                      emit_ref_reg(A_LEA,S_L,r,R_ESI);
@@ -623,7 +588,7 @@ implementation
                                       loadesi:=false;
                                       loadesi:=false;
 
 
                                     { a class destructor needs a flag }
                                     { a class destructor needs a flag }
-                                    if pobjectdef(methodpointer.resulttype)^.is_class and
+                                    if is_class(pobjectdef(methodpointer.resulttype)) and
                                        {assigned(aktprocsym) and
                                        {assigned(aktprocsym) and
                                        (aktprocsym^.definition^.proctypeoption=potype_destructor)}
                                        (aktprocsym^.definition^.proctypeoption=potype_destructor)}
                                        (procdefinition^.proctypeoption=potype_destructor) then
                                        (procdefinition^.proctypeoption=potype_destructor) then
@@ -633,7 +598,7 @@ implementation
                                       end;
                                       end;
 
 
                                     if not(is_con_or_destructor and
                                     if not(is_con_or_destructor and
-                                           pobjectdef(methodpointer.resulttype)^.is_class and
+                                           is_class(methodpointer.resulttype) and
                                            {assigned(aktprocsym) and
                                            {assigned(aktprocsym) and
                                           (aktprocsym^.definition^.proctypeoption in [potype_constructor,potype_destructor])}
                                           (aktprocsym^.definition^.proctypeoption in [potype_constructor,potype_destructor])}
                                            (procdefinition^.proctypeoption in [potype_constructor,potype_destructor])
                                            (procdefinition^.proctypeoption in [potype_constructor,potype_destructor])
@@ -644,8 +609,8 @@ implementation
                                     { will be made                                  }
                                     { will be made                                  }
                                     { con- and destructors need a pointer to the vmt }
                                     { con- and destructors need a pointer to the vmt }
                                     if is_con_or_destructor and
                                     if is_con_or_destructor and
-                                    not(pobjectdef(methodpointer.resulttype)^.is_class) and
-                                    assigned(aktprocsym) then
+                                      is_object(methodpointer.resulttype) and
+                                      assigned(aktprocsym) then
                                       begin
                                       begin
                                          if not(aktprocsym^.definition^.proctypeoption in
                                          if not(aktprocsym^.definition^.proctypeoption in
                                                 [potype_constructor,potype_destructor]) then
                                                 [potype_constructor,potype_destructor]) then
@@ -654,12 +619,13 @@ implementation
                                     { class destructors get there flag above }
                                     { class destructors get there flag above }
                                     { constructor flags ?                    }
                                     { constructor flags ?                    }
                                     if is_con_or_destructor and
                                     if is_con_or_destructor and
-                                        not(pobjectdef(methodpointer.resulttype)^.is_class and
+                                      not(
+                                        is_class(methodpointer.resulttype) and
                                         assigned(aktprocsym) and
                                         assigned(aktprocsym) and
                                         (aktprocsym^.definition^.proctypeoption=potype_destructor)) then
                                         (aktprocsym^.definition^.proctypeoption=potype_destructor)) then
                                       begin
                                       begin
                                          { a constructor needs also a flag }
                                          { a constructor needs also a flag }
-                                         if pobjectdef(methodpointer.resulttype)^.is_class then
+                                         if is_class(methodpointer.resulttype) then
                                            push_int(0);
                                            push_int(0);
                                          push_int(0);
                                          push_int(0);
                                       end;
                                       end;
@@ -713,8 +679,7 @@ implementation
                                             else
                                             else
                                               begin
                                               begin
                                                  if (methodpointer.resulttype^.deftype=classrefdef) or
                                                  if (methodpointer.resulttype^.deftype=classrefdef) or
-                                                    ((methodpointer.resulttype^.deftype=objectdef) and
-                                                   pobjectdef(methodpointer.resulttype)^.is_class) then
+                                                    is_class_or_interface(methodpointer.resulttype) then
                                                    emit_ref_reg(A_MOV,S_L,
                                                    emit_ref_reg(A_MOV,S_L,
                                                      newreference(methodpointer.location.reference),R_ESI)
                                                      newreference(methodpointer.location.reference),R_ESI)
                                                  else
                                                  else
@@ -742,14 +707,12 @@ implementation
 
 
                                         { direct call to destructor: remove data }
                                         { direct call to destructor: remove data }
                                         if (procdefinition^.proctypeoption=potype_destructor) and
                                         if (procdefinition^.proctypeoption=potype_destructor) and
-                                           (methodpointer.resulttype^.deftype=objectdef) and
-                                           (pobjectdef(methodpointer.resulttype)^.is_class) then
+                                           is_class(methodpointer.resulttype) then
                                           emit_const(A_PUSH,S_L,1);
                                           emit_const(A_PUSH,S_L,1);
 
 
                                         { direct call to class constructor, don't allocate memory }
                                         { direct call to class constructor, don't allocate memory }
                                         if (procdefinition^.proctypeoption=potype_constructor) and
                                         if (procdefinition^.proctypeoption=potype_constructor) and
-                                           (methodpointer.resulttype^.deftype=objectdef) and
-                                           (pobjectdef(methodpointer.resulttype)^.is_class) then
+                                           is_class(methodpointer.resulttype) then
                                           begin
                                           begin
                                              emit_const(A_PUSH,S_L,0);
                                              emit_const(A_PUSH,S_L,0);
                                              emit_const(A_PUSH,S_L,0);
                                              emit_const(A_PUSH,S_L,0);
@@ -759,8 +722,7 @@ implementation
                                              { constructor call via classreference => allocate memory }
                                              { constructor call via classreference => allocate memory }
                                              if (procdefinition^.proctypeoption=potype_constructor) and
                                              if (procdefinition^.proctypeoption=potype_constructor) and
                                                 (methodpointer.resulttype^.deftype=classrefdef) and
                                                 (methodpointer.resulttype^.deftype=classrefdef) and
-                                                (pobjectdef(pclassrefdef(methodpointer.resulttype)^.
-                                                   pointertype.def)^.is_class) then
+                                                is_class(pclassrefdef(methodpointer.resulttype)^.pointertype.def) then
                                                 emit_const(A_PUSH,S_L,1);
                                                 emit_const(A_PUSH,S_L,1);
                                              emit_reg(A_PUSH,S_L,R_ESI);
                                              emit_reg(A_PUSH,S_L,R_ESI);
                                           end;
                                           end;
@@ -769,8 +731,7 @@ implementation
                                     if is_con_or_destructor then
                                     if is_con_or_destructor then
                                       begin
                                       begin
                                          { classes don't get a VMT pointer pushed }
                                          { classes don't get a VMT pointer pushed }
-                                         if (methodpointer.resulttype^.deftype=objectdef) and
-                                           not(pobjectdef(methodpointer.resulttype)^.is_class) then
+                                         if is_object(methodpointer.resulttype) then
                                            begin
                                            begin
                                               if (procdefinition^.proctypeoption=potype_constructor) then
                                               if (procdefinition^.proctypeoption=potype_constructor) then
                                                 begin
                                                 begin
@@ -810,7 +771,7 @@ implementation
                              loadesi:=false;
                              loadesi:=false;
                           end;
                           end;
                         { direct call to destructor: don't remove data! }
                         { direct call to destructor: don't remove data! }
-                        if procinfo^._class^.is_class then
+                        if is_class(procinfo^._class) then
                           begin
                           begin
                              if (procdefinition^.proctypeoption=potype_destructor) then
                              if (procdefinition^.proctypeoption=potype_destructor) then
                                begin
                                begin
@@ -825,7 +786,7 @@ implementation
                              else
                              else
                                emit_reg(A_PUSH,S_L,R_ESI);
                                emit_reg(A_PUSH,S_L,R_ESI);
                           end
                           end
-                        else
+                        else if is_object(procinfo^._class) then
                           begin
                           begin
                              emit_reg(A_PUSH,S_L,R_ESI);
                              emit_reg(A_PUSH,S_L,R_ESI);
                              if is_con_or_destructor then
                              if is_con_or_destructor then
@@ -841,7 +802,9 @@ implementation
                                   else
                                   else
                                     push_int(0);
                                     push_int(0);
                                end;
                                end;
-                          end;
+                          end
+                        else
+                          Internalerror(200006165);
                      end;
                      end;
                 end;
                 end;
 
 
@@ -1356,8 +1319,7 @@ implementation
                 begin
                 begin
                    { data which must be finalized ? }
                    { data which must be finalized ? }
                    if (resulttype^.needs_inittable) and
                    if (resulttype^.needs_inittable) and
-                     ( (resulttype^.deftype<>objectdef) or
-                       not(pobjectdef(resulttype)^.is_class)) then
+                     not(is_class(resulttype)) then
                       finalize(resulttype,location.reference,false);
                       finalize(resulttype,location.reference,false);
                    { release unused temp }
                    { release unused temp }
                    ungetiftemp(location.reference)
                    ungetiftemp(location.reference)
@@ -1595,7 +1557,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2000-11-04 13:12:14  jonas
+  Revision 1.4  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.3  2000/11/04 13:12:14  jonas
     * check for nil pointers before calling getcopy
     * check for nil pointers before calling getcopy
 
 
   Revision 1.2  2000/10/31 22:02:56  peter
   Revision 1.2  2000/10/31 22:02:56  peter

+ 7 - 2
compiler/i386/n386cnv.pas

@@ -1234,7 +1234,9 @@ implementation
            @ti386typeconvnode.second_proc_to_procvar,
            @ti386typeconvnode.second_proc_to_procvar,
            @ti386typeconvnode.second_nothing, {arrayconstructor_to_set}
            @ti386typeconvnode.second_nothing, {arrayconstructor_to_set}
            @ti386typeconvnode.second_load_smallset,
            @ti386typeconvnode.second_load_smallset,
-           @ti386typeconvnode.second_cord_to_pointer
+           @ti386typeconvnode.second_cord_to_pointer,
+           @ti386typeconvnode.second_nothing, { interface 2 string }
+           @ti386typeconvnode.second_nothing  { interface 2 guid   }
          );
          );
       type
       type
          tprocedureofobject = procedure of object;
          tprocedureofobject = procedure of object;
@@ -1434,7 +1436,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:56  peter
+  Revision 1.3  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:56  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/15 09:33:31  peter
   Revision 1.1  2000/10/15 09:33:31  peter

+ 213 - 0
compiler/i386/n386ic.pas

@@ -0,0 +1,213 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by Kovacs Attila Zoltan
+
+    Generate i386 assembly wrapper code interface implementor objects
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit n386ic;
+
+interface
+
+uses
+  aasm,
+  symbase,symtype,symtable,symdef,symsym;
+
+procedure cgintfwrapper(asmlist: paasmoutput; procdef: pprocdef; const labelname: string; ioffset: longint);
+
+implementation
+
+uses
+  globtype, systems,
+  cobjects, verbose, globals,
+  symconst, types,
+{$ifdef GDB}
+  strings, gdb,
+{$endif GDB}
+  hcodegen, temp_gen,
+  cpubase, cpuasm,
+  cgai386, tgeni386;
+
+{
+possible calling conventions:
+              default stdcall cdecl pascal popstack register saveregisters
+default(0):      OK     OK    OK(1)  OK     OK(1)      OK          OK
+virtual(2):      OK     OK    OK(3)  OK     OK(3)      OK          OK(4)
+
+(0):
+    set self parameter to correct value
+    jmp mangledname
+
+(1): The code is the following
+     set self parameter to correct value
+     call mangledname
+     set self parameter to interface value
+
+(2): The wrapper code use %eax to reach the virtual method address
+     set self to correct value
+     move self,%eax
+     mov  0(%eax),%eax ; load vmt
+     jmp  vmtoffs(%eax) ; method offs
+
+(3): The wrapper code use %eax to reach the virtual method address
+     set self to correct value
+     move self,%eax
+     mov  0(%eax),%eax ; load vmt
+     jmp  vmtoffs(%eax) ; method offs
+     set self parameter to interface value
+
+
+(4): Virtual use eax to reach the method address so the following code be generated:
+     set self to correct value
+     push %ebx ; allocate space for function address
+     push %eax
+     mov  self,%eax
+     mov  0(%eax),%eax ; load vmt
+     mov  vmtoffs(%eax),eax ; method offs
+     mov  %eax,4(%esp)
+     pop  %eax
+     ret  0; jmp the address
+
+}
+
+function getselfoffsetfromsp(procdef: pprocdef): longint;
+begin
+  if not assigned(procdef^.parast^.symindex^.first) then
+    getselfoffsetfromsp:=4
+  else
+    if psym(procdef^.parast^.symindex^.first)^.typ=varsym then
+      getselfoffsetfromsp:=pvarsym(procdef^.parast^.symindex^.first)^.address+4
+    else
+      Internalerror(2000061310);
+end;
+
+
+procedure cgintfwrapper(asmlist: paasmoutput; procdef: pprocdef; const labelname: string; ioffset: longint);
+  procedure checkvirtual;
+  begin
+    if (procdef^.extnumber=-1) then
+      Internalerror(200006139);
+  end;
+
+  procedure adjustselfvalue(ioffset: longint);
+  begin
+    { sub $ioffset,offset(%esp) }
+    emit_const_ref(A_SUB,S_L,ioffset,new_reference(R_ESP,getselfoffsetfromsp(procdef)));
+  end;
+
+  procedure getselftoeax(offs: longint);
+  begin
+    { mov offset(%esp),%eax }
+    emit_ref_reg(A_MOV,S_L,new_reference(R_ESP,getselfoffsetfromsp(procdef)),R_EAX);
+  end;
+
+  procedure loadvmttoeax;
+  begin
+    checkvirtual;
+    { mov  0(%eax),%eax ; load vmt}
+    emit_ref_reg(A_MOV,S_L,new_reference(R_EAX,0),R_EAX);
+  end;
+
+  procedure op_oneaxmethodaddr(op: TAsmOp);
+  begin
+    { call/jmp  vmtoffs(%eax) ; method offs }
+    emit_ref(op,S_L,new_reference(R_EAX,procdef^._class^.vmtmethodoffset(procdef^.extnumber)));
+  end;
+
+  procedure loadmethodoffstoeax;
+  begin
+    { mov  vmtoffs(%eax),%eax ; method offs }
+    emit_ref_reg(A_MOV,S_L,new_reference(R_EAX,procdef^._class^.vmtmethodoffset(procdef^.extnumber)),R_EAX);
+  end;
+
+var
+  oldexprasmlist: paasmoutput;
+begin
+  if procdef^.proctypeoption<>potype_none then
+    Internalerror(200006137);
+  if not assigned(procdef^._class) or
+     (procdef^.procoptions*[po_containsself, po_classmethod, po_staticmethod,
+       po_methodpointer, po_interrupt, po_iocheck]<>[]) then
+    Internalerror(200006138);
+
+  oldexprasmlist:=exprasmlist;
+  exprasmlist:=asmlist;
+
+  exprasmlist^.concat(new(pai_symbol,initname(labelname,0)));
+
+  { set param1 interface to self  }
+  adjustselfvalue(ioffset);
+
+  { case 1  or 2 }
+  if (pocall_clearstack in procdef^.proccalloptions) then
+    begin
+      if po_virtualmethod in procdef^.procoptions then
+        begin { case 2 }
+          getselftoeax(0);
+          loadvmttoeax;
+          op_oneaxmethodaddr(A_CALL);
+        end
+      else { case 1 }
+        begin
+          emitcall(procdef^.mangledname);
+        end;
+      { restore param1 value self to interface }
+      adjustselfvalue(-ioffset);
+    end
+  { case 3 }
+  else if [po_virtualmethod,po_saveregisters]*procdef^.procoptions=[po_virtualmethod,po_saveregisters] then
+    begin
+      emit_reg(A_PUSH,S_L,R_EBX); { allocate space for address}
+      emit_reg(A_PUSH,S_L,R_EAX);
+      getselftoeax(8);
+      loadvmttoeax;
+      loadmethodoffstoeax;
+      { mov %eax,4(%esp) }
+      emit_reg_ref(A_MOV,S_L,R_EAX,new_reference(R_ESP,4));
+      { pop  %eax }
+      emit_reg(A_POP,S_L,R_EAX);
+      { ret  ; jump to the address }
+      emit_none(A_RET,S_L);
+    end
+  { case 4 }
+  else if po_virtualmethod in procdef^.procoptions then
+    begin
+      getselftoeax(0);
+      loadvmttoeax;
+      op_oneaxmethodaddr(A_JMP);
+    end
+  { case 0 }
+  else
+    begin
+      emitcall(procdef^.mangledname);
+    end;
+  exprasmlist:=oldexprasmlist;
+end;
+
+end.
+{
+  $Log$
+  Revision 1.1  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.1.2.2  2000/06/15 15:05:30  kaz
+    * An minor bug fix
+
+  Revision 1.1.2.1  2000/06/15 06:26:34  kaz
+    * Initial version
+}

+ 11 - 7
compiler/i386/n386ld.pas

@@ -315,9 +315,7 @@ implementation
                               begin
                               begin
                                  hregister:=left.location.register;
                                  hregister:=left.location.register;
                                  ungetregister32(left.location.register);
                                  ungetregister32(left.location.register);
-                                 if (left.resulttype^.deftype<>classrefdef) and
-                                    (left.resulttype^.deftype<>objectdef) and
-                                    not(pobjectdef(left.resulttype)^.is_class) then
+                                 if is_object(left.resulttype) then
                                    CGMessage(cg_e_illegal_expression);
                                    CGMessage(cg_e_illegal_expression);
                               end;
                               end;
 
 
@@ -328,7 +326,7 @@ implementation
                                  getexplicitregister32(R_EDI);
                                  getexplicitregister32(R_EDI);
 {$endif noAllocEdi}
 {$endif noAllocEdi}
                                  hregister:=R_EDI;
                                  hregister:=R_EDI;
-                                 if pobjectdef(left.resulttype)^.is_class then
+                                 if is_class_or_interface(left.resulttype) then
                                    emit_ref_reg(A_MOV,S_L,
                                    emit_ref_reg(A_MOV,S_L,
                                      newreference(left.location.reference),R_EDI)
                                      newreference(left.location.reference),R_EDI)
                                  else
                                  else
@@ -555,6 +553,10 @@ implementation
                   del_reference(right.location.reference);
                   del_reference(right.location.reference);
                 end
                 end
            end
            end
+        else if is_interfacecom(left.resulttype) then
+          begin
+             loadinterfacecom(self);
+          end
         else case right.location.loc of
         else case right.location.loc of
             LOC_REFERENCE,
             LOC_REFERENCE,
             LOC_MEM : begin
             LOC_MEM : begin
@@ -624,8 +626,7 @@ implementation
                          else
                          else
                            begin
                            begin
                               if (right.resulttype^.needs_inittable) and
                               if (right.resulttype^.needs_inittable) and
-                                ( (right.resulttype^.deftype<>objectdef) or
-                                  not(pobjectdef(right.resulttype)^.is_class)) then
+                                  not(is_class(right.resulttype)) then
                                 begin
                                 begin
                                    { this would be a problem }
                                    { this would be a problem }
                                    if not(left.resulttype^.needs_inittable) then
                                    if not(left.resulttype^.needs_inittable) then
@@ -1064,7 +1065,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:56  peter
+  Revision 1.3  2000-11-04 14:25:23  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:56  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/15 09:33:31  peter
   Revision 1.1  2000/10/15 09:33:31  peter

+ 13 - 9
compiler/i386/n386mem.pas

@@ -370,9 +370,8 @@ implementation
          secondpass(left);
          secondpass(left);
          if codegenerror then
          if codegenerror then
            exit;
            exit;
-         { classes must be dereferenced implicit }
-         if (left.resulttype^.deftype=objectdef) and
-           pobjectdef(left.resulttype)^.is_class then
+         { classes and interfaces must be dereferenced implicit }
+         if is_class_or_interface(left.resulttype) then
            begin
            begin
              reset_reference(location.reference);
              reset_reference(location.reference);
              case left.location.loc of
              case left.location.loc of
@@ -399,6 +398,11 @@ implementation
                   end;
                   end;
              end;
              end;
            end
            end
+         else if is_interfacecom(left.resulttype) then
+           begin
+              gettempintfcomreference(location.reference);
+              emit_mov_loc_ref(left.location,location.reference,S_L,false);
+           end
          else
          else
            set_location(location,left.location);
            set_location(location,left.location);
 
 
@@ -895,9 +899,7 @@ implementation
          reset_reference(location.reference);
          reset_reference(location.reference);
          getexplicitregister32(R_ESI);
          getexplicitregister32(R_ESI);
          if (resulttype^.deftype=classrefdef) or
          if (resulttype^.deftype=classrefdef) or
-           ((resulttype^.deftype=objectdef)
-             and pobjectdef(resulttype)^.is_class
-           ) then
+           is_class(resulttype) then
            location.register:=R_ESI
            location.register:=R_ESI
          else
          else
            location.reference.base:=R_ESI;
            location.reference.base:=R_ESI;
@@ -938,8 +940,7 @@ implementation
                  end
                  end
                else
                else
                 { call can have happend with a property }
                 { call can have happend with a property }
-                if (left.resulttype^.deftype=objectdef) and
-                   pobjectdef(left.resulttype)^.is_class then
+                if is_class_or_interface(left.resulttype) then
                  begin
                  begin
 {$ifndef noAllocEdi}
 {$ifndef noAllocEdi}
                     getexplicitregister32(R_EDI);
                     getexplicitregister32(R_EDI);
@@ -1052,7 +1053,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2000-10-31 22:02:57  peter
+  Revision 1.5  2000-11-04 14:25:24  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.4  2000/10/31 22:02:57  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.3  2000/10/31 14:18:53  jonas
   Revision 1.3  2000/10/31 14:18:53  jonas

+ 54 - 3
compiler/i386/n386util.pas

@@ -43,6 +43,7 @@ interface
     procedure loadshortstring(source,dest : tnode);
     procedure loadshortstring(source,dest : tnode);
     procedure loadlongstring(p:tbinarynode);
     procedure loadlongstring(p:tbinarynode);
     procedure loadansi2short(source,dest : tnode);
     procedure loadansi2short(source,dest : tnode);
+    procedure loadinterfacecom(p: tbinarynode);
 
 
     procedure maketojumpbool(p : tnode);
     procedure maketojumpbool(p : tnode);
     procedure emitoverflowcheck(p:tnode);
     procedure emitoverflowcheck(p:tnode);
@@ -696,8 +697,8 @@ implementation
                            ) and
                            ) and
                            (p.resulttype^.size<=4)
                            (p.resulttype^.size<=4)
                           ) or
                           ) or
-                          ((p.resulttype^.deftype=objectdef) and
-                           pobjectdef(p.resulttype)^.is_class) then
+                          is_class(p.resulttype) or
+                          is_interface(p.resulttype) then
                          begin
                          begin
                             if (p.resulttype^.size>2) or
                             if (p.resulttype^.size>2) or
                                ((alignment=4) and (p.resulttype^.size>0)) then
                                ((alignment=4) and (p.resulttype^.size>0)) then
@@ -1311,11 +1312,61 @@ implementation
          maybe_loadesi;
          maybe_loadesi;
       end;
       end;
 
 
+    procedure loadinterfacecom(p: tbinarynode);
+    {
+      copies an com interface from n.right to n.left, we
+      assume, that both sides are com interface, firstassignement have
+      to take care of that, an com interface can't be a register variable
+    }
+      var
+         pushed : tpushed;
+         ungettemp : boolean;
+      begin
+         { before pushing any parameter, we have to save all used      }
+         { registers, but before that we have to release the       }
+         { registers of that node to save uneccessary pushed       }
+         { so be careful, if you think you can optimize that code (FK) }
+
+         { nevertheless, this has to be changed, because otherwise the }
+         { register is released before it's contents are pushed ->     }
+         { problems with the optimizer (JM)                         }
+         del_reference(p.left.location.reference);
+         ungettemp:=false;
+         case p.right.location.loc of
+            LOC_REGISTER,LOC_CREGISTER:
+              begin
+                 pushusedregisters(pushed, $ff xor ($80 shr byte(p.right.location.register)));
+                 exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,p.right.location.register)));
+                 ungetregister32(p.right.location.register);
+              end;
+            LOC_REFERENCE,LOC_MEM:
+              begin
+                 pushusedregisters(pushed,$ff
+                   xor ($80 shr byte(p.right.location.reference.base))
+                   xor ($80 shr byte(p.right.location.reference.index)));
+                 emit_push_mem(p.right.location.reference);
+                 del_reference(p.right.location.reference);
+                 ungettemp:=true;
+              end;
+         end;
+         emitpushreferenceaddr(p.left.location.reference);
+         del_reference(p.left.location.reference);
+         emitcall('FPC_INTF_ASSIGN');
+         maybe_loadesi;
+         popusedregisters(pushed);
+         if ungettemp then
+           ungetiftemp(p.right.location.reference);
+      end;
+
+
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:57  peter
+  Revision 1.3  2000-11-04 14:25:25  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:57  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/15 09:33:32  peter
   Revision 1.1  2000/10/15 09:33:32  peter

+ 9 - 2
compiler/msgidx.inc

@@ -74,6 +74,7 @@ const
   scan_e_invalid_maxfpureg_value=02055;
   scan_e_invalid_maxfpureg_value=02055;
   scan_w_only_one_resourcefile_supported=02056;
   scan_w_only_one_resourcefile_supported=02056;
   scan_w_macro_support_turned_off=02057;
   scan_w_macro_support_turned_off=02057;
+  scan_e_invalid_interface_type=02058;
   parser_e_syntax_error=03000;
   parser_e_syntax_error=03000;
   parser_w_proc_far_ignored=03001;
   parser_w_proc_far_ignored=03001;
   parser_w_proc_near_ignored=03002;
   parser_w_proc_near_ignored=03002;
@@ -239,6 +240,11 @@ const
   parser_f_need_objfpc_or_delphi_mode=03162;
   parser_f_need_objfpc_or_delphi_mode=03162;
   parser_e_no_export_with_index_for_target=03163;
   parser_e_no_export_with_index_for_target=03163;
   parser_e_no_export_of_variables_for_target=03164;
   parser_e_no_export_of_variables_for_target=03164;
+  parser_e_improper_guid_syntax=03165;
+  parser_f_interface_cant_have_variables=03166;
+  parser_f_interface_cant_have_constr_or_destr=03167;
+  parser_w_interface_mapping_notfound=03168;
+  parser_e_interface_id_expected=03169;
   type_e_mismatch=04000;
   type_e_mismatch=04000;
   type_e_incompatible_types=04001;
   type_e_incompatible_types=04001;
   type_e_not_equal_types=04002;
   type_e_not_equal_types=04002;
@@ -273,6 +279,7 @@ const
   type_e_no_assign_to_addr=04031;
   type_e_no_assign_to_addr=04031;
   type_e_no_assign_to_const=04032;
   type_e_no_assign_to_const=04032;
   type_e_array_required=04033;
   type_e_array_required=04033;
+  type_e_interface_type_expected=04034;
   sym_e_id_not_found=05000;
   sym_e_id_not_found=05000;
   sym_f_internal_error_in_symtablestack=05001;
   sym_f_internal_error_in_symtablestack=05001;
   sym_e_duplicate_id=05002;
   sym_e_duplicate_id=05002;
@@ -557,9 +564,9 @@ const
   option_info=11024;
   option_info=11024;
   option_help_pages=11025;
   option_help_pages=11025;
 
 
-  MsgTxtSize = 31225;
+  MsgTxtSize = 31647;
 
 
   MsgIdxMax : array[1..20] of longint=(
   MsgIdxMax : array[1..20] of longint=(
-    17,58,165,34,41,41,86,14,35,40,
+    17,59,170,35,41,41,86,14,35,40,
     26,1,1,1,1,1,1,1,1,1
     26,1,1,1,1,1,1,1,1,1
   );
   );

+ 269 - 257
compiler/msgtxt.inc

@@ -1,7 +1,7 @@
 {$ifdef Delphi}
 {$ifdef Delphi}
-const msgtxt : array[0..000130] of string[240]=(
+const msgtxt : array[0..000131] of string[240]=(
 {$else Delphi}
 {$else Delphi}
-const msgtxt : array[0..000130,1..240] of char=(
+const msgtxt : array[0..000131,1..240] of char=(
 {$endif Delphi}
 {$endif Delphi}
   '01000_T_Compiler: $1'#000+
   '01000_T_Compiler: $1'#000+
   '01001_D_Compiler OS: $1'#000+
   '01001_D_Compiler OS: $1'#000+
@@ -81,526 +81,538 @@ const msgtxt : array[0..000130,1..240] of char=(
   '02055_E_Illegal value for FPU register limit'#000+
   '02055_E_Illegal value for FPU register limit'#000+
   '02056_W_Only one resource file is supported for this target'#000+
   '02056_W_Only one resource file is supported for this target'#000+
   '02057_W_Macro support has been turned off'#000+
   '02057_W_Macro support has been turned off'#000+
+  '02058_E_Illegal interface type specified.',' Valids are COM, CORBA or D'+
+  'EFAULT.'#000+
   '03000_E_Parser - Syntax Error'#000+
   '03000_E_Parser - Syntax Error'#000+
-  '03001_W_Pro','cedure type FAR ignored'#000+
+  '03001_W_Procedure type FAR ignored'#000+
   '03002_W_Procedure type NEAR ignored'#000+
   '03002_W_Procedure type NEAR ignored'#000+
   '03003_W_Procedure type INTERRUPT ignored for not i386'#000+
   '03003_W_Procedure type INTERRUPT ignored for not i386'#000+
   '03004_E_INTERRUPT procedure can'#039't be nested'#000+
   '03004_E_INTERRUPT procedure can'#039't be nested'#000+
-  '03005_W_Procedure type "$1" ignored'#000+
-  '03006_E_Not all declarations of "$1" are decla','red with OVERLOAD'#000+
+  '03005_','W_Procedure type "$1" ignored'#000+
+  '03006_E_Not all declarations of "$1" are declared with OVERLOAD'#000+
   '03007_E_No DLL File specified'#000+
   '03007_E_No DLL File specified'#000+
   '03008_E_Duplicate exported function name "$1"'#000+
   '03008_E_Duplicate exported function name "$1"'#000+
   '03009_E_Duplicate exported function index $1'#000+
   '03009_E_Duplicate exported function index $1'#000+
-  '03010_E_Invalid index for exported function'#000+
-  '03011_W_Relocatable DLL or executable $1 debug info does ','not work, d'+
-  'isabled.'#000+
+  '03010_E_Invalid index for',' exported function'#000+
+  '03011_W_Relocatable DLL or executable $1 debug info does not work, dis'+
+  'abled.'#000+
   '03012_W_To allow debugging for win32 code you need to disable relocati'+
   '03012_W_To allow debugging for win32 code you need to disable relocati'+
   'on with -WN option'#000+
   'on with -WN option'#000+
   '03013_E_Constructor name must be INIT'#000+
   '03013_E_Constructor name must be INIT'#000+
-  '03014_E_Destructor name must be DONE'#000+
+  '03014_E_Destructo','r name must be DONE'#000+
   '03015_E_Illegal open parameter'#000+
   '03015_E_Illegal open parameter'#000+
-  '03016_E_Procedure type IN','LINE not supported'#000+
+  '03016_E_Procedure type INLINE not supported'#000+
   '03017_W_Private methods shouldn'#039't be VIRTUAL'#000+
   '03017_W_Private methods shouldn'#039't be VIRTUAL'#000+
   '03018_W_Constructor should be public'#000+
   '03018_W_Constructor should be public'#000+
   '03019_W_Destructor should be public'#000+
   '03019_W_Destructor should be public'#000+
-  '03020_N_Class should have one destructor only'#000+
+  '03020_N_Class should have o','ne destructor only'#000+
   '03021_E_Local class definitions are not allowed'#000+
   '03021_E_Local class definitions are not allowed'#000+
-  '03022_F_A','nonym class definitions are not allowed'#000+
+  '03022_F_Anonym class definitions are not allowed'#000+
   '03023_E_The object "$1" has no VMT'#000+
   '03023_E_The object "$1" has no VMT'#000+
   '03024_E_Illegal parameter list'#000+
   '03024_E_Illegal parameter list'#000+
   '03025_E_Wrong parameter type specified for arg no. "$1"'#000+
   '03025_E_Wrong parameter type specified for arg no. "$1"'#000+
-  '03026_E_Wrong amount of parameters specified'#000+
-  '03027_E_overloaded identifier "$1','" isn'#039't a function'#000+
+  '03','026_E_Wrong amount of parameters specified'#000+
+  '03027_E_overloaded identifier "$1" isn'#039't a function'#000+
   '03028_E_overloaded functions have the same parameter list'#000+
   '03028_E_overloaded functions have the same parameter list'#000+
   '03029_E_function header doesn'#039't match the forward declaration "$1"'+
   '03029_E_function header doesn'#039't match the forward declaration "$1"'+
   #000+
   #000+
-  '03030_E_function header "$1" doesn'#039't match forward : var name chan'+
-  'ges $2 => $3'#000+
-  '03031_N_Values in',' enumeration types have to be ascending'#000+
+  '03030_E_function hea','der "$1" doesn'#039't match forward : var name ch'+
+  'anges $2 => $3'#000+
+  '03031_N_Values in enumeration types have to be ascending'#000+
   '03032_N_Interface and implementation names are different "$1" => "$2"'#000+
   '03032_N_Interface and implementation names are different "$1" => "$2"'#000+
-  '03033_E_With can not be used for variables in a different segment'#000+
+  '03033_E_With can not be used for variables in a differ','ent segment'#000+
   '03034_E_function nesting > 31'#000+
   '03034_E_function nesting > 31'#000+
-  '03035_E_range check error while ev','aluating constants'#000+
+  '03035_E_range check error while evaluating constants'#000+
   '03036_W_range check error while evaluating constants'#000+
   '03036_W_range check error while evaluating constants'#000+
   '03037_E_duplicate case label'#000+
   '03037_E_duplicate case label'#000+
   '03038_E_Upper bound of case range is less than lower bound'#000+
   '03038_E_Upper bound of case range is less than lower bound'#000+
-  '03039_E_typed constants of classes are not allowed'#000+
-  '03040_E_functions variables o','f overloaded functions are not allowed'#000+
+  '0303','9_E_typed constants of classes are not allowed'#000+
+  '03040_E_functions variables of overloaded functions are not allowed'#000+
   '03041_E_string length must be a value from 1 to 255'#000+
   '03041_E_string length must be a value from 1 to 255'#000+
   '03042_W_use extended syntax of NEW and DISPOSE for instances of object'+
   '03042_W_use extended syntax of NEW and DISPOSE for instances of object'+
   's'#000+
   's'#000+
-  '03043_W_use of NEW or DISPOSE for untyped pointers is meaningless'#000+
-  '03044_E_use',' of NEW or DISPOSE is not possible for untyped pointers'#000+
+  '0','3043_W_use of NEW or DISPOSE for untyped pointers is meaningless'#000+
+  '03044_E_use of NEW or DISPOSE is not possible for untyped pointers'#000+
   '03045_E_class identifier expected'#000+
   '03045_E_class identifier expected'#000+
   '03046_E_type identifier not allowed here'#000+
   '03046_E_type identifier not allowed here'#000+
-  '03047_E_method identifier expected'#000+
+  '03047_E_method identifier expecte','d'#000+
   '03048_E_function header doesn'#039't match any method of this class "$1'+
   '03048_E_function header doesn'#039't match any method of this class "$1'+
   '"'#000+
   '"'#000+
-  '03049_','P_procedure/function $1'#000+
+  '03049_P_procedure/function $1'#000+
   '03050_E_Illegal floating point constant'#000+
   '03050_E_Illegal floating point constant'#000+
   '03051_E_FAIL can be used in constructors only'#000+
   '03051_E_FAIL can be used in constructors only'#000+
   '03052_E_Destructors can'#039't have parameters'#000+
   '03052_E_Destructors can'#039't have parameters'#000+
-  '03053_E_Only class methods can be referred with class references'#000+
-  '03054_E_Only class meth','ods can be accessed in class methods'#000+
+  '03053_E_Only',' class methods can be referred with class references'#000+
+  '03054_E_Only class methods can be accessed in class methods'#000+
   '03055_E_Constant and CASE types do not match'#000+
   '03055_E_Constant and CASE types do not match'#000+
   '03056_E_The symbol can'#039't be exported from a library'#000+
   '03056_E_The symbol can'#039't be exported from a library'#000+
-  '03057_W_An inherited method is hidden by "$1"'#000+
-  '03058_E_There is no method in an ancestor class to be overri','dden: "$'+
-  '1"'#000+
+  '03057_W_An inherited method is',' hidden by "$1"'#000+
+  '03058_E_There is no method in an ancestor class to be overridden: "$1"'+
+  #000+
   '03059_E_No member is provided to access property'#000+
   '03059_E_No member is provided to access property'#000+
   '03060_W_Stored prorperty directive is not yet implemented'#000+
   '03060_W_Stored prorperty directive is not yet implemented'#000+
   '03061_E_Illegal symbol for property access'#000+
   '03061_E_Illegal symbol for property access'#000+
-  '03062_E_Cannot access a protected field of an object here'#000+
-  '03063_E_Cannot access',' a private field of an object here'#000+
+  '030','62_E_Cannot access a protected field of an object here'#000+
+  '03063_E_Cannot access a private field of an object here'#000+
   '03064_W_overloaded method of virtual method should be virtual: "$1"'#000+
   '03064_W_overloaded method of virtual method should be virtual: "$1"'#000+
-  '03065_W_overloaded method of non-virtual method should be non-virtual:'+
-  ' "$1"'#000+
-  '03066_E_overloaded methods which are virtual must have the sa','me retu'+
-  'rn type: "$1"'#000+
+  '03065_W_overloaded method of non-virtual method should be non','-virtua'+
+  'l: "$1"'#000+
+  '03066_E_overloaded methods which are virtual must have the same return'+
+  ' type: "$1"'#000+
   '03067_E_EXPORT declared functions can'#039't be nested'#000+
   '03067_E_EXPORT declared functions can'#039't be nested'#000+
   '03068_E_methods can'#039't be EXPORTed'#000+
   '03068_E_methods can'#039't be EXPORTed'#000+
-  '03069_E_call by var parameters have to match exactly: Got "$1" expecte'+
-  'd "$2"'#000+
+  '03069_E_call by var parameters have to match exactly: Got "','$1" expec'+
+  'ted "$2"'#000+
   '03070_E_Class isn'#039't a parent class of the current class'#000+
   '03070_E_Class isn'#039't a parent class of the current class'#000+
-  '03','071_E_SELF is only allowed in methods'#000+
+  '03071_E_SELF is only allowed in methods'#000+
   '03072_E_methods can be only in other methods called direct with type i'+
   '03072_E_methods can be only in other methods called direct with type i'+
   'dentifier of the class'#000+
   'dentifier of the class'#000+
   '03073_E_Illegal use of '#039':'#039#000+
   '03073_E_Illegal use of '#039':'#039#000+
-  '03074_E_range check error in set constructor or duplicate set element'#000+
-  '03075_E_Poin','ter to object expected'#000+
+  '03074_','E_range check error in set constructor or duplicate set elemen'+
+  't'#000+
+  '03075_E_Pointer to object expected'#000+
   '03076_E_Expression must be constructor call'#000+
   '03076_E_Expression must be constructor call'#000+
   '03077_E_Expression must be destructor call'#000+
   '03077_E_Expression must be destructor call'#000+
   '03078_E_Illegal order of record elements'#000+
   '03078_E_Illegal order of record elements'#000+
-  '03079_E_Expression type must be class or record type'#000+
-  '03080_E_Procedures can'#039't return a va','lue'#000+
+  '03079_E_Expre','ssion type must be class or record type'#000+
+  '03080_E_Procedures can'#039't return a value'#000+
   '03081_E_constructors and destructors must be methods'#000+
   '03081_E_constructors and destructors must be methods'#000+
   '03082_E_Operator is not overloaded'#000+
   '03082_E_Operator is not overloaded'#000+
   '03083_E_Impossible to overload assignment for equal types'#000+
   '03083_E_Impossible to overload assignment for equal types'#000+
-  '03084_E_Impossible operator overload'#000+
+  '03084_E_Imposs','ible operator overload'#000+
   '03085_E_Re-raise isn'#039't possible there'#000+
   '03085_E_Re-raise isn'#039't possible there'#000+
-  '03086_E_The ext','ended syntax of new or dispose isn'#039't allowed for '+
-  'a class'#000+
+  '03086_E_The extended syntax of new or dispose isn'#039't allowed for a '+
+  'class'#000+
   '03087_E_Assembler incompatible with function return type'#000+
   '03087_E_Assembler incompatible with function return type'#000+
   '03088_E_Procedure overloading is switched off'#000+
   '03088_E_Procedure overloading is switched off'#000+
-  '03089_E_It is not possible to overload this operator (overload = inste'+
-  'ad)'#000+
-  '03090_','E_Comparative operator must return a boolean value'#000+
+  '0308','9_E_It is not possible to overload this operator (overload = ins'+
+  'tead)'#000+
+  '03090_E_Comparative operator must return a boolean value'#000+
   '03091_E_Only virtual methods can be abstract'#000+
   '03091_E_Only virtual methods can be abstract'#000+
   '03092_F_Use of unsupported feature!'#000+
   '03092_F_Use of unsupported feature!'#000+
-  '03093_E_The mix of CLASSES and OBJECTS isn'#039't allowed'#000+
-  '03094_W_Unknown procedure directive had to be ignored: ','"$1"'#000+
+  '03093_E_The mix of different kin','d of objects (class, object, interfa'+
+  'ce, raw interface etc) isn'#039't allowed'#000+
+  '03094_W_Unknown procedure directive had to be ignored: "$1"'#000+
   '03095_E_absolute can only be associated to ONE variable'#000+
   '03095_E_absolute can only be associated to ONE variable'#000+
-  '03096_E_absolute can only be associated a var or const'#000+
+  '03096_E_absolute can only be associated a var or co','nst'#000+
   '03097_E_Only ONE variable can be initialized'#000+
   '03097_E_Only ONE variable can be initialized'#000+
   '03098_E_Abstract methods shouldn'#039't have any definition (with funct'+
   '03098_E_Abstract methods shouldn'#039't have any definition (with funct'+
   'ion body)'#000+
   'ion body)'#000+
-  '030','99_E_This overloaded function can'#039't be local (must be exporte'+
-  'd)'#000+
-  '03100_W_Virtual methods are used without a constructor in "$1"'#000+
+  '03099_E_This overloaded function can'#039't be local (must be exported)'+
+  #000+
+  '03100_W_Virtual methods are used without a const','ructor in "$1"'#000+
   '03101_M_Macro defined: $1'#000+
   '03101_M_Macro defined: $1'#000+
   '03102_M_Macro undefined: $1'#000+
   '03102_M_Macro undefined: $1'#000+
   '03103_M_Macro $1 set to $2'#000+
   '03103_M_Macro $1 set to $2'#000+
   '03104_I_Compiling $1'#000+
   '03104_I_Compiling $1'#000+
-  '03105_U_Par','sing interface of unit $1'#000+
+  '03105_U_Parsing interface of unit $1'#000+
   '03106_U_Parsing implementation of $1'#000+
   '03106_U_Parsing implementation of $1'#000+
   '03107_D_Compiling $1 for the second time'#000+
   '03107_D_Compiling $1 for the second time'#000+
-  '03108_E_Array properties aren'#039't allowed here'#000+
+  '03108_E_','Array properties aren'#039't allowed here'#000+
   '03109_E_No property found to override'#000+
   '03109_E_No property found to override'#000+
-  '03110_E_Only one default property is allowed, found i','nherited defaul'+
-  't property in class "$1"'#000+
+  '03110_E_Only one default property is allowed, found inherited default '+
+  'property in class "$1"'#000+
   '03111_E_The default property must be an array property'#000+
   '03111_E_The default property must be an array property'#000+
-  '03112_E_Virtual constructors are only supported in class object model'#000+
+  '03112_E_Virtual c','onstructors are only supported in class object mode'+
+  'l'#000+
   '03113_E_No default property available'#000+
   '03113_E_No default property available'#000+
-  '03114_E_The class can'#039't have a publis','hed section, use the {$M+} '+
-  'switch'#000+
+  '03114_E_The class can'#039't have a published section, use the {$M+} sw'+
+  'itch'#000+
   '03115_E_Forward declaration of class "$1" must be resolved here to use'+
   '03115_E_Forward declaration of class "$1" must be resolved here to use'+
-  ' the class as ancestor'#000+
+  ' the cla','ss as ancestor'#000+
   '03116_E_Local operators not supported'#000+
   '03116_E_Local operators not supported'#000+
   '03117_E_Procedure directive "$1" not allowed in interface section'#000+
   '03117_E_Procedure directive "$1" not allowed in interface section'#000+
-  '03118_E_P','rocedure directive "$1" not allowed in implementation secti'+
-  'on'#000+
-  '03119_E_Procedure directive "$1" not allowed in procvar declaration'#000+
+  '03118_E_Procedure directive "$1" not allowed in implementation section'+
+  #000+
+  '03119_E_Procedure directive "$1" not allowed in pr','ocvar declaration'#000+
   '03120_E_Function is already declared Public/Forward "$1"'#000+
   '03120_E_Function is already declared Public/Forward "$1"'#000+
   '03121_E_Can'#039't use both EXPORT and EXTERNAL'#000+
   '03121_E_Can'#039't use both EXPORT and EXTERNAL'#000+
-  '03122_E_NA','ME keyword expected'#000+
+  '03122_E_NAME keyword expected'#000+
   '03123_W_"$1" not yet supported inside inline procedure/function'#000+
   '03123_W_"$1" not yet supported inside inline procedure/function'#000+
   '03124_W_Inlining disabled'#000+
   '03124_W_Inlining disabled'#000+
-  '03125_I_Writing Browser log $1'#000+
+  '03','125_I_Writing Browser log $1'#000+
   '03126_H_may be pointer dereference is missing'#000+
   '03126_H_may be pointer dereference is missing'#000+
   '03127_F_Selected assembler reader not supported'#000+
   '03127_F_Selected assembler reader not supported'#000+
-  '03128','_E_Procedure directive "$1" has conflicts with other directives'+
-  #000+
-  '03129_E_Calling convention doesn'#039't match forward'#000+
+  '03128_E_Procedure directive "$1" has conflicts with other directives'#000+
+  '03129_E_Calling convention doesn'#039't match forward',#000+
   '03130_E_Register calling (fastcall) not supported'#000+
   '03130_E_Register calling (fastcall) not supported'#000+
   '03131_E_Property can'#039't have a default value'#000+
   '03131_E_Property can'#039't have a default value'#000+
-  '03132_E_The default value of a pr','operty must be constant'#000+
+  '03132_E_The default value of a property must be constant'#000+
   '03133_E_Symbol can'#039't be published, can be only a class'#000+
   '03133_E_Symbol can'#039't be published, can be only a class'#000+
-  '03134_E_That kind of property can'#039't be published'#000+
+  '03134_E_That kind of property can',#039't be published'#000+
   '03135_W_Empty import name specified'#000+
   '03135_W_Empty import name specified'#000+
   '03136_W_An import name is required'#000+
   '03136_W_An import name is required'#000+
-  '03137_E_Function internal name changed af','ter use of function'#000+
+  '03137_E_Function internal name changed after use of function'#000+
   '03138_E_Division by zero'#000+
   '03138_E_Division by zero'#000+
   '03139_E_Invalid floating point operation'#000+
   '03139_E_Invalid floating point operation'#000+
-  '03140_E_Upper bound of range is less than lower bound'#000+
+  '03140_E_Upper bound of ran','ge is less than lower bound'#000+
   '03141_W_string "$1" is longer than "$2"'#000+
   '03141_W_string "$1" is longer than "$2"'#000+
   '03142_E_string length is larger than array of char length'#000+
   '03142_E_string length is larger than array of char length'#000+
-  '03','143_E_Illegal expression after message directive'#000+
-  '03144_E_Message handlers can take only one call by ref. parameter'#000+
+  '03143_E_Illegal expression after message directive'#000+
+  '03144_E_Message handlers can take only one call by ref. paramet','er'#000+
   '03145_E_Duplicate message label: "$1"'#000+
   '03145_E_Duplicate message label: "$1"'#000+
   '03146_E_Self can be only an explicit parameter in message handlers'#000+
   '03146_E_Self can be only an explicit parameter in message handlers'#000+
-  '03147_E_Threadvars c','an be only static or global'#000+
+  '03147_E_Threadvars can be only static or global'#000+
   '03148_F_Direct assembler not supported for binary output format'#000+
   '03148_F_Direct assembler not supported for binary output format'#000+
-  '03149_W_Don'#039't load OBJPAS unit manual, use {$mode objfpc} or {$mod'+
-  'e delphi} instead'#000+
+  '03149_W_Don'#039't load O','BJPAS unit manual, use {$mode objfpc} or {$m'+
+  'ode delphi} instead'#000+
   '03150_E_OVERRIDE can'#039't be used in objects'#000+
   '03150_E_OVERRIDE can'#039't be used in objects'#000+
-  '03151_E_Data types whi','ch requires initialization/finalization can'#039+
-  't be used in variant records'#000+
-  '03152_E_Resourcestrings can be only static or global'#000+
+  '03151_E_Data types which requires initialization/finalization can'#039't'+
+  ' be used in variant records'#000+
+  '03152_E_Resourcestrings can be only sta','tic or global'#000+
   '03153_E_Exit with argument can'#039't be used here'#000+
   '03153_E_Exit with argument can'#039't be used here'#000+
   '03154_E_The type of the storage symbol must be boolean'#000+
   '03154_E_The type of the storage symbol must be boolean'#000+
-  '03155_E_This ','symbol isn'#039't allowed as storage symbol'#000+
+  '03155_E_This symbol isn'#039't allowed as storage symbol'#000+
   '03156_E_Only class which are compiled in $M+ mode can be published'#000+
   '03156_E_Only class which are compiled in $M+ mode can be published'#000+
-  '03157_E_Procedure directive expected'#000+
+  '03157_','E_Procedure directive expected'#000+
   '03158_E_The value for a property index must be of an ordinal type'#000+
   '03158_E_The value for a property index must be of an ordinal type'#000+
-  '03159_E_Procedure name to short',' to be exported'#000+
+  '03159_E_Procedure name to short to be exported'#000+
   '03160_E_No DEFFILE entry can be generated for unit global vars'#000+
   '03160_E_No DEFFILE entry can be generated for unit global vars'#000+
-  '03161_E_Compile without -WD option'#000+
+  '03161_E_Compile without -WD optio','n'#000+
   '03162_F_You need ObjFpc (-S2) or Delphi (-Sd) mode to compile this mod'+
   '03162_F_You need ObjFpc (-S2) or Delphi (-Sd) mode to compile this mod'+
   'ule'#000+
   'ule'#000+
   '03163_E_Can'#039't export with index under $1'#000+
   '03163_E_Can'#039't export with index under $1'#000+
-  '03164_E_Exp','orting of variables is not supported under $1'#000+
+  '03164_E_Exporting of variables is not supported under $1'#000+
+  '03165_E_Improper GUID syntax'#000+
+  '03166_F_An interface can'#039't have varia','bles'#000+
+  '03167_F_An interface can'#039't have constructor or destructor'#000+
+  '03168_W_Procedure named $1 not found that is suitable for implementing'+
+  ' the $2.$3'#000+
+  '03169_E_interface identifier expected'#000+
   '04000_E_Type mismatch'#000+
   '04000_E_Type mismatch'#000+
-  '04001_E_Incompatible types: got "$1" expected "$2"'#000+
+  '04001_E_Incompatible types: got "$1"',' expected "$2"'#000+
   '04002_E_Type mismatch between "$1" and "$2"'#000+
   '04002_E_Type mismatch between "$1" and "$2"'#000+
   '04003_E_Type identifier expected'#000+
   '04003_E_Type identifier expected'#000+
   '04004_E_Variable identifier expected'#000+
   '04004_E_Variable identifier expected'#000+
-  '04005_E','_Integer expression expected, but got "$1"'#000+
+  '04005_E_Integer expression expected, but got "$1"'#000+
   '04006_E_Boolean expression expected, but got "$1"'#000+
   '04006_E_Boolean expression expected, but got "$1"'#000+
-  '04007_E_Ordinal expression expected'#000+
+  '04007_E_Ord','inal expression expected'#000+
   '04008_E_pointer type expected, but got "$1"'#000+
   '04008_E_pointer type expected, but got "$1"'#000+
   '04009_E_class type expected, but got "$1"'#000+
   '04009_E_class type expected, but got "$1"'#000+
-  '04010_E_Variable or type ','indentifier expected'#000+
+  '04010_E_Variable or type indentifier expected'#000+
   '04011_E_Can'#039't evaluate constant expression'#000+
   '04011_E_Can'#039't evaluate constant expression'#000+
-  '04012_E_Set elements are not compatible'#000+
+  '04012_E_Set elements are not compatible'#000,
   '04013_E_Operation not implemented for sets'#000+
   '04013_E_Operation not implemented for sets'#000+
   '04014_W_Automatic type conversion from floating type to COMP which is '+
   '04014_W_Automatic type conversion from floating type to COMP which is '+
   'an integer type'#000+
   'an integer type'#000+
-  '04015_H','_use DIV instead to get an integer result'#000+
+  '04015_H_use DIV instead to get an integer result'#000+
   '04016_E_string types doesn'#039't match, because of $V+ mode'#000+
   '04016_E_string types doesn'#039't match, because of $V+ mode'#000+
-  '04017_E_succ or pred on enums with assignments not possible'#000+
+  '04017_','E_succ or pred on enums with assignments not possible'#000+
   '04018_E_Can'#039't read or write variables of this type'#000+
   '04018_E_Can'#039't read or write variables of this type'#000+
-  '04019_E_Can'#039't use readln or wri','teln on typed file'#000+
+  '04019_E_Can'#039't use readln or writeln on typed file'#000+
   '04020_E_Can'#039't use read or write on untyped file.'#000+
   '04020_E_Can'#039't use read or write on untyped file.'#000+
-  '04021_E_Type conflict between set elements'#000+
+  '04021_E_Type conflict between set el','ements'#000+
   '04022_W_lo/hi(dword/qword) returns the upper/lower word/dword'#000+
   '04022_W_lo/hi(dword/qword) returns the upper/lower word/dword'#000+
   '04023_E_Integer or real expression expected'#000+
   '04023_E_Integer or real expression expected'#000+
-  '04024_E_Wrong type "$1"',' in array constructor'#000+
+  '04024_E_Wrong type "$1" in array constructor'#000+
   '04025_E_Incompatible type for arg no. $1: Got "$2", expected "$3"'#000+
   '04025_E_Incompatible type for arg no. $1: Got "$2", expected "$3"'#000+
-  '04026_E_Method (variable) and Procedure (variable) are not compatible'#000+
+  '04026_E_Method (','variable) and Procedure (variable) are not compatibl'+
+  'e'#000+
   '04027_E_Illegal constant passed to internal math function'#000+
   '04027_E_Illegal constant passed to internal math function'#000+
-  '04028_E_Can'#039't get the ad','dress of constants'#000+
+  '04028_E_Can'#039't get the address of constants'#000+
   '04029_E_Argument can'#039't be assigned to'#000+
   '04029_E_Argument can'#039't be assigned to'#000+
-  '04030_E_Can'#039't assign local procedure/function to procedure variabl'+
-  'e'#000+
+  '04030_E_Can'#039't assign local procedure/function t','o procedure varia'+
+  'ble'#000+
   '04031_E_Can'#039't assign values to an address'#000+
   '04031_E_Can'#039't assign values to an address'#000+
   '04032_E_Can'#039't assign values to const variable'#000+
   '04032_E_Can'#039't assign values to const variable'#000+
-  '04033_E_Array type required',#000+
+  '04033_E_Array type required'#000+
+  '04034_E_interface type expected, but got "$1"'#000+
   '05000_E_Identifier not found "$1"'#000+
   '05000_E_Identifier not found "$1"'#000+
-  '05001_F_Internal Error in SymTableStack()'#000+
+  '05001_F_Internal Error ','in SymTableStack()'#000+
   '05002_E_Duplicate identifier "$1"'#000+
   '05002_E_Duplicate identifier "$1"'#000+
   '05003_H_Identifier already defined in $1 at line $2'#000+
   '05003_H_Identifier already defined in $1 at line $2'#000+
   '05004_E_Unknown identifier "$1"'#000+
   '05004_E_Unknown identifier "$1"'#000+
   '05005_E_Forward declaration not solved "$1"'#000+
   '05005_E_Forward declaration not solved "$1"'#000+
-  '0','5006_F_Identifier type already defined as type'#000+
-  '05007_E_Error in type definition'#000+
+  '05006_F_Identifier type already defined as type'#000+
+  '05007_E_Err','or in type definition'#000+
   '05008_E_Type identifier not defined'#000+
   '05008_E_Type identifier not defined'#000+
   '05009_E_Forward type not resolved "$1"'#000+
   '05009_E_Forward type not resolved "$1"'#000+
   '05010_E_Only static variables can be used in static methods or outside'+
   '05010_E_Only static variables can be used in static methods or outside'+
   ' methods'#000+
   ' methods'#000+
-  '05011_','E_Invalid call to tvarsym.mangledname()'#000+
-  '05012_F_record or class type expected'#000+
+  '05011_E_Invalid call to tvarsym.mangledname()'#000+
+  '05012_F_record or ','class type expected'#000+
   '05013_E_Instances of classes or objects with an abstract method are no'+
   '05013_E_Instances of classes or objects with an abstract method are no'+
   't allowed'#000+
   't allowed'#000+
   '05014_W_Label not defined "$1"'#000+
   '05014_W_Label not defined "$1"'#000+
   '05015_E_Label used but not defined "$1"'#000+
   '05015_E_Label used but not defined "$1"'#000+
-  '05016_E_Ill','egal label declaration'#000+
-  '05017_E_GOTO and LABEL are not supported (use switch -Sg)'#000+
+  '05016_E_Illegal label declaration'#000+
+  '05017_E_GOTO and LABEL are not supp','orted (use switch -Sg)'#000+
   '05018_E_Label not found'#000+
   '05018_E_Label not found'#000+
   '05019_E_identifier isn'#039't a label'#000+
   '05019_E_identifier isn'#039't a label'#000+
   '05020_E_label already defined'#000+
   '05020_E_label already defined'#000+
   '05021_E_illegal type declaration of set elements'#000+
   '05021_E_illegal type declaration of set elements'#000+
-  '05022_E_Forward class d','efinition not resolved "$1"'#000+
-  '05023_H_Unit "$1" not used in $2'#000+
+  '05022_E_Forward class definition not resolved "$1"'#000+
+  '05023_H_Unit "$1" not used in ','$2'#000+
   '05024_H_Parameter "$1" not used'#000+
   '05024_H_Parameter "$1" not used'#000+
   '05025_N_Local variable "$1" not used'#000+
   '05025_N_Local variable "$1" not used'#000+
   '05026_H_Value parameter "$1" is assigned but never used'#000+
   '05026_H_Value parameter "$1" is assigned but never used'#000+
-  '05027_N_Local variable "$1" is assigned but never used',#000+
+  '05027_N_Local variable "$1" is assigned but never used'#000+
   '05028_H_Local $1 "$2" is not used'#000+
   '05028_H_Local $1 "$2" is not used'#000+
-  '05029_N_Private field "$1.$2" is never used'#000+
+  '05029_N_Private field "','$1.$2" is never used'#000+
   '05030_N_Private field "$1.$2" is assigned but never used'#000+
   '05030_N_Private field "$1.$2" is assigned but never used'#000+
   '05031_N_Private method "$1.$2" never used'#000+
   '05031_N_Private method "$1.$2" never used'#000+
   '05032_E_Set type expected'#000+
   '05032_E_Set type expected'#000+
-  '05033_W_Function result does not see','m to be set'#000+
-  '05034_W_Type "$1" is not aligned correctly in current record for C'#000+
+  '05033_W_Function result does not seem to be set'#000+
+  '05034_W_Type "$1" is not aligned correctly in ','current record for C'#000+
   '05035_E_Unknown record field identifier "$1"'#000+
   '05035_E_Unknown record field identifier "$1"'#000+
   '05036_W_Local variable "$1" does not seem to be initialized'#000+
   '05036_W_Local variable "$1" does not seem to be initialized'#000+
   '05037_W_Variable "$1" does not seem to be initialized'#000+
   '05037_W_Variable "$1" does not seem to be initialized'#000+
-  '05','038_E_identifier idents no member "$1"'#000+
-  '05039_B_Found declaration: $1'#000+
+  '05038_E_identifier idents no member "$1"'#000+
+  '05039_B_Found decla','ration: $1'#000+
   '05040_E_Data segment too large (max. 2GB)'#000+
   '05040_E_Data segment too large (max. 2GB)'#000+
   '06000_E_BREAK not allowed'#000+
   '06000_E_BREAK not allowed'#000+
   '06001_E_CONTINUE not allowed'#000+
   '06001_E_CONTINUE not allowed'#000+
   '06002_E_Expression too complicated - FPU stack overflow'#000+
   '06002_E_Expression too complicated - FPU stack overflow'#000+
-  '06003_E_Illegal ex','pression'#000+
+  '06003_E_Illegal expression'#000+
   '06004_E_Invalid integer expression'#000+
   '06004_E_Invalid integer expression'#000+
-  '06005_E_Illegal qualifier'#000+
+  '06005_E_Illega','l qualifier'#000+
   '06006_E_High range limit < low range limit'#000+
   '06006_E_High range limit < low range limit'#000+
   '06007_E_Illegal counter variable'#000+
   '06007_E_Illegal counter variable'#000+
   '06008_E_Can'#039't determine which overloaded function to call'#000+
   '06008_E_Can'#039't determine which overloaded function to call'#000+
-  '06009_E_Parameter list size exceeds ','65535 bytes'#000+
+  '06009_E_Parameter list size exceeds 65535 bytes'#000+
   '06010_E_Illegal type conversion'#000+
   '06010_E_Illegal type conversion'#000+
-  '06011_D_Conversion between ordinals and pointers is not portable acros'+
-  's platforms'#000+
+  '06011_D_Conver','sion between ordinals and pointers is not portable acr'+
+  'oss platforms'#000+
   '06012_E_File types must be var parameters'#000+
   '06012_E_File types must be var parameters'#000+
   '06013_E_The use of a far pointer isn'#039't allowed there'#000+
   '06013_E_The use of a far pointer isn'#039't allowed there'#000+
-  '06014_E_illegal cal','l by reference parameters'#000+
-  '06015_E_EXPORT declared functions can'#039't be called'#000+
+  '06014_E_illegal call by reference parameters'#000+
+  '06015_E_EXPORT declared function','s can'#039't be called'#000+
   '06016_W_Possible illegal call of constructor or destructor (doesn'#039't'+
   '06016_W_Possible illegal call of constructor or destructor (doesn'#039't'+
   ' match to this context)'#000+
   ' match to this context)'#000+
   '06017_N_Inefficient code'#000+
   '06017_N_Inefficient code'#000+
   '06018_W_unreachable code'#000+
   '06018_W_unreachable code'#000+
-  '06019_E_procedure call ','with stackframe ESP/SP'#000+
-  '06020_E_Abstract methods can'#039't be called directly'#000+
+  '06019_E_procedure call with stackframe ESP/SP'#000+
+  '06020_E_Abstract methods can'#039't be c','alled directly'#000+
   '06021_F_Internal Error in getfloatreg(), allocation failure'#000+
   '06021_F_Internal Error in getfloatreg(), allocation failure'#000+
   '06022_F_Unknown float type'#000+
   '06022_F_Unknown float type'#000+
   '06023_F_SecondVecn() base defined twice'#000+
   '06023_F_SecondVecn() base defined twice'#000+
   '06024_F_Extended cg68k not supported'#000+
   '06024_F_Extended cg68k not supported'#000+
-  '060','25_F_32-bit unsigned not supported in MC68000 mode'#000+
-  '06026_F_Internal Error in secondinline()'#000+
+  '06025_F_32-bit unsigned not supported in MC68000 mode'#000+
+  '06026_F','_Internal Error in secondinline()'#000+
   '06027_D_Register $1 weight $2 $3'#000+
   '06027_D_Register $1 weight $2 $3'#000+
   '06028_E_Stack limit excedeed in local routine'#000+
   '06028_E_Stack limit excedeed in local routine'#000+
   '06029_D_Stack frame is omitted'#000+
   '06029_D_Stack frame is omitted'#000+
-  '06030_W_Range check for 64 bit integer','s is not supported on this tar'+
-  'get'#000+
-  '06031_E_Object or class methods can'#039't be inline.'#000+
+  '06030_W_Range check for 64 bit integers is not supported on this targe'+
+  't'#000+
+  '06031_E_Object or class ','methods can'#039't be inline.'#000+
   '06032_E_Procvar calls can'#039't be inline.'#000+
   '06032_E_Procvar calls can'#039't be inline.'#000+
   '06033_E_No code for inline procedure stored'#000+
   '06033_E_No code for inline procedure stored'#000+
   '06034_E_Direct call of interrupt procedure "$1" is not possible'#000+
   '06034_E_Direct call of interrupt procedure "$1" is not possible'#000+
-  '06035_E_El','ement zero of an ansi/wide- or longstring can'#039't be acc'+
-  'essed, use (set)length instead'#000+
+  '06035_E_Element zero of an ansi/wide- or longstring can'#039't be acces'+
+  'se','d, use (set)length instead'#000+
   '06036_E_Include and exclude not implemented in this case'#000+
   '06036_E_Include and exclude not implemented in this case'#000+
   '06037_E_Constructors or destructors can not be called inside a '#039'wi'+
   '06037_E_Constructors or destructors can not be called inside a '#039'wi'+
   'th'#039' clause'#000+
   'th'#039' clause'#000+
-  '06038_E_Cannot call m','essage handler method directly'#000+
-  '06039_E_Jump in or outside of an exception block'#000+
+  '06038_E_Cannot call message handler method directly'#000+
+  '06039_E_Jump in or outside ','of an exception block'#000+
   '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+
   '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+
   '07000_D_Starting $1 styled assembler parsing'#000+
   '07000_D_Starting $1 styled assembler parsing'#000+
   '07001_D_Finished $1 styled assembler parsing'#000+
   '07001_D_Finished $1 styled assembler parsing'#000+
-  '0700','2_E_Non-label pattern contains @'#000+
-  '07003_W_Override operator not supported'#000+
+  '07002_E_Non-label pattern contains @'#000+
+  '07003_W_Override operator',' not supported'#000+
   '07004_E_Error building record offset'#000+
   '07004_E_Error building record offset'#000+
   '07005_E_OFFSET used without identifier'#000+
   '07005_E_OFFSET used without identifier'#000+
   '07006_E_TYPE used without identifier'#000+
   '07006_E_TYPE used without identifier'#000+
   '07007_E_Cannot use local variable or parameters here'#000+
   '07007_E_Cannot use local variable or parameters here'#000+
-  '0','7008_E_need to use OFFSET here'#000+
-  '07009_E_need to use $ here'#000+
+  '07008_E_need to use OFFSET here'#000+
+  '07009_E_need to use $ here'#000,
   '07010_E_Cannot use multiple relocatable symbols'#000+
   '07010_E_Cannot use multiple relocatable symbols'#000+
   '07011_E_Relocatable symbol can only be added'#000+
   '07011_E_Relocatable symbol can only be added'#000+
   '07012_E_Invalid constant expression'#000+
   '07012_E_Invalid constant expression'#000+
   '07013_E_Relocatable symbol is not allowed'#000+
   '07013_E_Relocatable symbol is not allowed'#000+
-  '07014_E_Inv','alid reference syntax'#000+
-  '07015_E_You can not reach $1 from that code'#000+
+  '07014_E_Invalid reference syntax'#000+
+  '07015_E_You can not reach $1 from th','at code'#000+
   '07016_E_Local symbols/labels aren'#039't allowed as references'#000+
   '07016_E_Local symbols/labels aren'#039't allowed as references'#000+
   '07017_E_Invalid base and index register usage'#000+
   '07017_E_Invalid base and index register usage'#000+
   '07018_W_Possible error in object field handling'#000+
   '07018_W_Possible error in object field handling'#000+
-  '07019_E_Wrong scale fa','ctor specified'#000+
+  '07019_E_Wrong scale factor specified'#000+
   '07020_E_Multiple index register usage'#000+
   '07020_E_Multiple index register usage'#000+
-  '07021_E_Invalid operand type'#000+
+  '07021','_E_Invalid operand type'#000+
   '07022_E_Invalid string as opcode operand: $1'#000+
   '07022_E_Invalid string as opcode operand: $1'#000+
   '07023_W_@CODE and @DATA not supported'#000+
   '07023_W_@CODE and @DATA not supported'#000+
   '07024_E_Null label references are not allowed'#000+
   '07024_E_Null label references are not allowed'#000+
-  '07025_E_Divide by zero in asm',' evaluator'#000+
+  '07025_E_Divide by zero in asm evaluator'#000+
   '07026_E_Illegal expression'#000+
   '07026_E_Illegal expression'#000+
-  '07027_E_escape sequence ignored: $1'#000+
+  '07027_E_escape seque','nce ignored: $1'#000+
   '07028_E_Invalid symbol reference'#000+
   '07028_E_Invalid symbol reference'#000+
   '07029_W_Fwait can cause emulation problems with emu387'#000+
   '07029_W_Fwait can cause emulation problems with emu387'#000+
   '07030_W_FADD without operand translated into FADDP'#000+
   '07030_W_FADD without operand translated into FADDP'#000+
-  '07031_W_ENTER instruction i','s not supported by Linux kernel'#000+
-  '07032_W_Calling an overload function in assembler'#000+
+  '07031_W_ENTER instruction is not supported by Linux kernel'#000+
+  '07032_W_Calling an overloa','d function in assembler'#000+
   '07033_E_Unsupported symbol type for operand'#000+
   '07033_E_Unsupported symbol type for operand'#000+
   '07034_E_Constant value out of bounds'#000+
   '07034_E_Constant value out of bounds'#000+
   '07035_E_Error converting decimal $1'#000+
   '07035_E_Error converting decimal $1'#000+
   '07036_E_Error converting octal $1'#000+
   '07036_E_Error converting octal $1'#000+
-  '07037_E','_Error converting binary $1'#000+
-  '07038_E_Error converting hexadecimal $1'#000+
+  '07037_E_Error converting binary $1'#000+
+  '07038_E_Error converting hexad','ecimal $1'#000+
   '07039_H_$1 translated to $2'#000+
   '07039_H_$1 translated to $2'#000+
   '07040_W_$1 is associated to an overloaded function'#000+
   '07040_W_$1 is associated to an overloaded function'#000+
   '07041_E_Cannot use SELF outside a method'#000+
   '07041_E_Cannot use SELF outside a method'#000+
-  '07042_E_Cannot use OLDEBP outside a nested procedure',#000+
+  '07042_E_Cannot use OLDEBP outside a nested procedure'#000+
   '07084_E_Cannot use RESULT in this function'#000+
   '07084_E_Cannot use RESULT in this function'#000+
-  '07085_H_RESULT is register $1'#000+
+  '07085_H_RESULT',' is register $1'#000+
   '07043_W_Procedures can'#039't return any value in asm code'#000+
   '07043_W_Procedures can'#039't return any value in asm code'#000+
   '07044_E_SEG not supported'#000+
   '07044_E_SEG not supported'#000+
   '07045_E_Size suffix and destination or source size do not match'#000+
   '07045_E_Size suffix and destination or source size do not match'#000+
-  '07046_W_Size suffix an','d destination or source size do not match'#000+
-  '07047_E_Assembler syntax error'#000+
+  '07046_W_Size suffix and destination or source size do not match'#000+
+  '07047_E_Assemble','r syntax error'#000+
   '07048_E_Invalid combination of opcode and operands'#000+
   '07048_E_Invalid combination of opcode and operands'#000+
   '07049_E_Assemler syntax error in operand'#000+
   '07049_E_Assemler syntax error in operand'#000+
   '07050_E_Assemler syntax error in constant'#000+
   '07050_E_Assemler syntax error in constant'#000+
-  '07051_E_Invalid String expression',#000+
+  '07051_E_Invalid String expression'#000+
   '07052_bit constant created for address'#000+
   '07052_bit constant created for address'#000+
-  '07053_E_Unrecognized opcode $1'#000+
+  '07053_E_Unrecogniz','ed opcode $1'#000+
   '07054_E_Invalid or missing opcode'#000+
   '07054_E_Invalid or missing opcode'#000+
   '07055_E_Invalid combination of prefix and opcode: $1'#000+
   '07055_E_Invalid combination of prefix and opcode: $1'#000+
   '07056_E_Invalid combination of override and opcode: $1'#000+
   '07056_E_Invalid combination of override and opcode: $1'#000+
-  '07057_E_Too many operands o','n line'#000+
+  '07057_E_Too many operands on line'#000+
   '07058_W_NEAR ignored'#000+
   '07058_W_NEAR ignored'#000+
   '07059_W_FAR ignored'#000+
   '07059_W_FAR ignored'#000+
-  '07060_E_Duplicate local symbol $1'#000+
+  '07060_E_Du','plicate local symbol $1'#000+
   '07061_E_Undefined local symbol $1'#000+
   '07061_E_Undefined local symbol $1'#000+
   '07062_E_Unknown label identifier $1'#000+
   '07062_E_Unknown label identifier $1'#000+
   '07063_E_Invalid register name'#000+
   '07063_E_Invalid register name'#000+
   '07064_E_Invalid floating point register name'#000+
   '07064_E_Invalid floating point register name'#000+
-  '07065_E_NOR n','ot supported'#000+
+  '07065_E_NOR not supported'#000+
   '07066_W_Modulo not supported'#000+
   '07066_W_Modulo not supported'#000+
-  '07067_E_Invalid floating point constant $1'#000+
+  '07067_E_Invalid ','floating point constant $1'#000+
   '07068_E_Invalid floating point expression'#000+
   '07068_E_Invalid floating point expression'#000+
   '07069_E_Wrong symbol type'#000+
   '07069_E_Wrong symbol type'#000+
   '07070_E_Cannot index a local var or parameter with a register'#000+
   '07070_E_Cannot index a local var or parameter with a register'#000+
-  '07071_E_Invalid segment o','verride expression'#000+
-  '07072_W_Identifier $1 supposed external'#000+
+  '07071_E_Invalid segment override expression'#000+
+  '07072_W_Identifier $1 supposed external',#000+
   '07073_E_Strings not allowed as constants'#000+
   '07073_E_Strings not allowed as constants'#000+
   '07074_No type of variable specified'#000+
   '07074_No type of variable specified'#000+
   '07075_E_assembler code not returned to text section'#000+
   '07075_E_assembler code not returned to text section'#000+
   '07076_E_Not a directive or local symbol $1'#000+
   '07076_E_Not a directive or local symbol $1'#000+
-  '07077_E_U','sing a defined name as a local label'#000+
-  '07078_E_Dollar token is used without an identifier'#000+
+  '07077_E_Using a defined name as a local label'#000+
+  '07078_E_Dollar token ','is used without an identifier'#000+
   '07079_W_32bit constant created for address'#000+
   '07079_W_32bit constant created for address'#000+
   '07080_N_.align is target specific, use .balign or .p2align'#000+
   '07080_N_.align is target specific, use .balign or .p2align'#000+
-  '07081_E_Can'#039't access fields directly for parameter','s'#000+
-  '07082_E_Can'#039't access fields of objects/classes directly'#000+
+  '07081_E_Can'#039't access fields directly for parameters'#000+
+  '07082_E_Can'#039't access fields of objects/classes directly'#000,
   '07083_E_No size specified and unable to determine the size of the oper'+
   '07083_E_No size specified and unable to determine the size of the oper'+
   'ands'#000+
   'ands'#000+
   '08000_F_Too many assembler files'#000+
   '08000_F_Too many assembler files'#000+
   '08001_F_Selected assembler output not supported'#000+
   '08001_F_Selected assembler output not supported'#000+
-  '08002_F_Comp not supported',#000+
+  '08002_F_Comp not supported'#000+
   '08003_F_Direct not support for binary writers'#000+
   '08003_F_Direct not support for binary writers'#000+
-  '08004_E_Allocating of data is only allowed in bss section'#000+
+  '08004_E_All','ocating of data is only allowed in bss section'#000+
   '08005_F_No binary writer selected'#000+
   '08005_F_No binary writer selected'#000+
   '08006_E_Asm: Opcode $1 not in table'#000+
   '08006_E_Asm: Opcode $1 not in table'#000+
   '08007_E_Asm: $1 invalid combination of opcode and operands'#000+
   '08007_E_Asm: $1 invalid combination of opcode and operands'#000+
-  '08008_','E_Asm: 16 Bit references not supported'#000+
-  '08009_E_Asm: Invalid effective address'#000+
+  '08008_E_Asm: 16 Bit references not supported'#000+
+  '08009_E_Asm: Invali','d effective address'#000+
   '08010_E_Asm: Immediate or reference expected'#000+
   '08010_E_Asm: Immediate or reference expected'#000+
   '08011_E_Asm: $1 value exceeds bounds $2'#000+
   '08011_E_Asm: $1 value exceeds bounds $2'#000+
   '08012_E_Asm: Short jump is out of range $1'#000+
   '08012_E_Asm: Short jump is out of range $1'#000+
   '08013_E_Asm: Undefined label $1'#000+
   '08013_E_Asm: Undefined label $1'#000+
-  '09','000_W_Source operating system redefined'#000+
-  '09001_I_Assembling (pipe) $1'#000+
+  '09000_W_Source operating system redefined'#000+
+  '09001_I_Assembling',' (pipe) $1'#000+
   '09002_E_Can'#039't create assember file: $1'#000+
   '09002_E_Can'#039't create assember file: $1'#000+
   '09003_E_Can'#039't create object file: $1'#000+
   '09003_E_Can'#039't create object file: $1'#000+
   '09004_E_Can'#039't create archive file: $1'#000+
   '09004_E_Can'#039't create archive file: $1'#000+
-  '09005_W_Assembler $1 not found, switching to external ass','embling'#000+
+  '09005_W_Assembler $1 not found, switching to external assembling'#000+
   '09006_T_Using assembler: $1'#000+
   '09006_T_Using assembler: $1'#000+
-  '09007_W_Error while assembling exitcode $1'#000+
+  '09007_W_Error while as','sembling exitcode $1'#000+
   '09008_W_Can'#039't call the assembler, error $1 switching to external a'+
   '09008_W_Can'#039't call the assembler, error $1 switching to external a'+
   'ssembling'#000+
   'ssembling'#000+
   '09009_I_Assembling $1'#000+
   '09009_I_Assembling $1'#000+
   '09010_I_Assembling smartlink $1'#000+
   '09010_I_Assembling smartlink $1'#000+
-  '09011_W_Object $1 not found, Li','nking may fail !'#000+
-  '09012_W_Library $1 not found, Linking may fail !'#000+
+  '09011_W_Object $1 not found, Linking may fail !'#000+
+  '09012_W_Library $1 not found, Linking may',' fail !'#000+
   '09013_W_Error while linking'#000+
   '09013_W_Error while linking'#000+
   '09014_W_Can'#039't call the linker, switching to external linking'#000+
   '09014_W_Can'#039't call the linker, switching to external linking'#000+
   '09015_I_Linking $1'#000+
   '09015_I_Linking $1'#000+
   '09016_W_Util $1 not found, switching to external linking'#000+
   '09016_W_Util $1 not found, switching to external linking'#000+
-  '09017_T_U','sing util $1'#000+
-  '09018_E_Creation of Executables not supported'#000+
+  '09017_T_Using util $1'#000+
+  '09018_E_Creation of Executables not supported',#000+
   '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+
   '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+
   '09020_I_Closing script $1'#000+
   '09020_I_Closing script $1'#000+
   '09021_W_resource compiler not found, switching to external mode'#000+
   '09021_W_resource compiler not found, switching to external mode'#000+
   '09022_I_Compiling resource $1'#000+
   '09022_I_Compiling resource $1'#000+
-  '09','023_T_unit $1 can'#039't be static linked, switching to smart linki'+
+  '09023_T_unit $1 can'#039't be static linked, switching to smart l','inki'+
   'ng'#000+
   'ng'#000+
   '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+
   '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+
   #000+
   #000+
   '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+
   '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+
   'g'#000+
   'g'#000+
-  '09026_E_unit $1 can'#039't be smart or static',' linked'#000+
+  '09026_E_unit $1 can'#039't be smart or static linked'#000+
   '09027_E_unit $1 can'#039't be shared or static linked'#000+
   '09027_E_unit $1 can'#039't be shared or static linked'#000+
-  '09028_F_Can'#039't post process executable $1'#000+
+  '0','9028_F_Can'#039't post process executable $1'#000+
   '09029_F_Can'#039't open executable $1'#000+
   '09029_F_Can'#039't open executable $1'#000+
   '09030_X_Size of Code: $1 bytes'#000+
   '09030_X_Size of Code: $1 bytes'#000+
   '09031_X_Size of initialized data: $1 bytes'#000+
   '09031_X_Size of initialized data: $1 bytes'#000+
-  '09032_X_Size of uninitialized data:',' $1 bytes'#000+
+  '09032_X_Size of uninitialized data: $1 bytes'#000+
   '09033_X_Stack space reserved: $1 bytes'#000+
   '09033_X_Stack space reserved: $1 bytes'#000+
-  '09034_X_Stack space commited: $1 bytes'#000+
+  '09034_X_S','tack space commited: $1 bytes'#000+
   '10000_T_Unitsearch: $1'#000+
   '10000_T_Unitsearch: $1'#000+
   '10001_T_PPU Loading $1'#000+
   '10001_T_PPU Loading $1'#000+
   '10002_U_PPU Name: $1'#000+
   '10002_U_PPU Name: $1'#000+
   '10003_U_PPU Flags: $1'#000+
   '10003_U_PPU Flags: $1'#000+
   '10004_U_PPU Crc: $1'#000+
   '10004_U_PPU Crc: $1'#000+
   '10005_U_PPU Time: $1'#000+
   '10005_U_PPU Time: $1'#000+
-  '10006_U_PPU File too s','hort'#000+
+  '10006_U_PPU File too short'#000+
   '10007_U_PPU Invalid Header (no PPU at the begin)'#000+
   '10007_U_PPU Invalid Header (no PPU at the begin)'#000+
-  '10008_U_PPU Invalid Version $1'#000+
+  '1000','8_U_PPU Invalid Version $1'#000+
   '10009_U_PPU is compiled for an other processor'#000+
   '10009_U_PPU is compiled for an other processor'#000+
   '10010_U_PPU is compiled for an other target'#000+
   '10010_U_PPU is compiled for an other target'#000+
   '10011_U_PPU Source: $1'#000+
   '10011_U_PPU Source: $1'#000+
   '10012_U_Writing $1'#000+
   '10012_U_Writing $1'#000+
-  '10013_F_Can'#039't Write PP','U-File'#000+
+  '10013_F_Can'#039't Write PPU-File'#000+
   '10014_F_Error reading PPU-File'#000+
   '10014_F_Error reading PPU-File'#000+
-  '10015_F_unexpected end of PPU-File'#000+
+  '10015_F_unexpected e','nd of PPU-File'#000+
   '10016_F_Invalid PPU-File entry: $1'#000+
   '10016_F_Invalid PPU-File entry: $1'#000+
   '10017_F_PPU Dbx count problem'#000+
   '10017_F_PPU Dbx count problem'#000+
   '10018_E_Illegal unit name: $1'#000+
   '10018_E_Illegal unit name: $1'#000+
   '10019_F_Too much units'#000+
   '10019_F_Too much units'#000+
-  '10020_F_Circular unit reference between $1 and $2',#000+
+  '10020_F_Circular unit reference between $1 and $2'#000+
   '10021_F_Can'#039't compile unit $1, no sources available'#000+
   '10021_F_Can'#039't compile unit $1, no sources available'#000+
-  '10022_F_Can'#039't find unit $1'#000+
+  '10022','_F_Can'#039't find unit $1'#000+
   '10023_W_Unit $1 was not found but $2 exists'#000+
   '10023_W_Unit $1 was not found but $2 exists'#000+
   '10024_F_Unit $1 searched but $2 found'#000+
   '10024_F_Unit $1 searched but $2 found'#000+
   '10025_W_Compiling the system unit requires the -Us switch'#000+
   '10025_W_Compiling the system unit requires the -Us switch'#000+
-  '10026_F_There were $','1 errors compiling module, stopping'#000+
-  '10027_U_Load from $1 ($2) unit $3'#000+
+  '10026_F_There were $1 errors compiling module, stopping'#000+
+  '10027_U_Load from $1 (','$2) unit $3'#000+
   '10028_U_Recompiling $1, checksum changed for $2'#000+
   '10028_U_Recompiling $1, checksum changed for $2'#000+
   '10029_U_Recompiling $1, source found only'#000+
   '10029_U_Recompiling $1, source found only'#000+
   '10030_U_Recompiling unit, static lib is older than ppufile'#000+
   '10030_U_Recompiling unit, static lib is older than ppufile'#000+
-  '10031_U_Recompiling u','nit, shared lib is older than ppufile'#000+
-  '10032_U_Recompiling unit, obj and asm are older than ppufile'#000+
+  '10031_U_Recompiling unit, shared lib is older than ppufile'#000+
+  '10032_U_Recompiling ','unit, obj and asm are older than ppufile'#000+
   '10033_U_Recompiling unit, obj is older than asm'#000+
   '10033_U_Recompiling unit, obj is older than asm'#000+
   '10034_U_Parsing interface of $1'#000+
   '10034_U_Parsing interface of $1'#000+
   '10035_U_Parsing implementation of $1'#000+
   '10035_U_Parsing implementation of $1'#000+
-  '10036_U_Second load for ','unit $1'#000+
+  '10036_U_Second load for unit $1'#000+
   '10037_U_PPU Check file $1 time $2'#000+
   '10037_U_PPU Check file $1 time $2'#000+
-  '10038_H_Conditional $1 was not set at startup in last compilation of $'+
-  '2'#000+
+  '10038_H_Conditio','nal $1 was not set at startup in last compilation of'+
+  ' $2'#000+
   '10039_H_Conditional $1 was set at startup in last compilation of $2'#000+
   '10039_H_Conditional $1 was set at startup in last compilation of $2'#000+
   '11000_$1 [options] <inputfile> [options]'#000+
   '11000_$1 [options] <inputfile> [options]'#000+
-  '11001_W_Only one ','source file supported'#000+
-  '11002_W_DEF file can be created only for OS/2'#000+
+  '11001_W_Only one source file supported'#000+
+  '11002_W_DEF file can be created only',' for OS/2'#000+
   '11003_E_nested response files are not supported'#000+
   '11003_E_nested response files are not supported'#000+
   '11004_F_No source file name in command line'#000+
   '11004_F_No source file name in command line'#000+
   '11005_N_No option inside $1 config file'#000+
   '11005_N_No option inside $1 config file'#000+
   '11006_E_Illegal parameter: $1'#000+
   '11006_E_Illegal parameter: $1'#000+
-  '11007_H_-?',' writes help pages'#000+
+  '11007_H_-? writes help pages'#000+
   '11008_F_Too many config files nested'#000+
   '11008_F_Too many config files nested'#000+
-  '11009_F_Unable to open file $1'#000+
+  '11','009_F_Unable to open file $1'#000+
   '11010_N_Reading further options from $1'#000+
   '11010_N_Reading further options from $1'#000+
   '11011_W_Target is already set to: $1'#000+
   '11011_W_Target is already set to: $1'#000+
   '11012_W_Shared libs not supported on DOS platform, reverting to static'+
   '11012_W_Shared libs not supported on DOS platform, reverting to static'+
   #000+
   #000+
-  '11013','_F_too many IF(N)DEFs'#000+
+  '11013_F_too many IF(N)DEFs'#000+
   '11014_F_too many ENDIFs'#000+
   '11014_F_too many ENDIFs'#000+
-  '11015_F_open conditional at the end of the file'#000+
+  '11015_F_open',' conditional at the end of the file'#000+
   '11016_W_Debug information generation is not supported by this executab'+
   '11016_W_Debug information generation is not supported by this executab'+
   'le'#000+
   'le'#000+
   '11017_H_Try recompiling with -dGDB'#000+
   '11017_H_Try recompiling with -dGDB'#000+
-  '11018_E_You are using the obsolete swi','tch $1'#000+
-  '11019_E_You are using the obsolete switch $1, please use $2'#000+
+  '11018_E_You are using the obsolete switch $1'#000+
+  '11019_E_You are using the obsolete switch $1, pleas','e use $2'#000+
   '11020_N_Switching assembler to default source writing assembler'#000+
   '11020_N_Switching assembler to default source writing assembler'#000+
   '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
   '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
   '11022_W_"$1" assembler use forced'#000+
   '11022_W_"$1" assembler use forced'#000+
-  '11023_Fr','ee Pascal Compiler version $FPCVER [$FPCDATE] for $FPCTARGET'+
+  '11023_Free Pascal Compiler version $FPCVER [$FPCDATE] for $FPCTARG','ET'+
   #010+
   #010+
   'Copyright (c) 1993-2000 by Florian Klaempfl'#000+
   'Copyright (c) 1993-2000 by Florian Klaempfl'#000+
   '11024_Free Pascal Compiler version $FPCVER'#010+
   '11024_Free Pascal Compiler version $FPCVER'#010+
@@ -608,158 +620,158 @@ const msgtxt : array[0..000130,1..240] of char=(
   'Compiler Date  : $FPCDATE'#010+
   'Compiler Date  : $FPCDATE'#010+
   'Compiler Target: $FPCTARGET'#010+
   'Compiler Target: $FPCTARGET'#010+
   #010+
   #010+
-  'This program comes under the GNU Gen','eral Public Licence'#010+
-  'For more information read COPYING.FPC'#010+
+  'This program comes under the GNU General Public Licence'#010+
+  'For more information read COPYING.FPC'#010,
   #010+
   #010+
   'Report bugs,suggestions etc to:'#010+
   'Report bugs,suggestions etc to:'#010+
   '                 [email protected]'#000+
   '                 [email protected]'#000+
   '11025_**0*_put + after a boolean switch option to enable it, - to disa'+
   '11025_**0*_put + after a boolean switch option to enable it, - to disa'+
   'ble it'#010+
   'ble it'#010+
-  '**1a_the compiler doesn'#039't delete ','the generated assembler file'#010+
-  '**2al_list sourcecode lines in assembler file'#010+
+  '**1a_the compiler doesn'#039't delete the generated assembler file'#010+
+  '**2al_list sourcecode lines i','n assembler file'#010+
   '**2ar_list register allocation/release info in assembler file'#010+
   '**2ar_list register allocation/release info in assembler file'#010+
   '**2at_list temp allocation/release info in assembler file'#010+
   '**2at_list temp allocation/release info in assembler file'#010+
   '**1b_generate browser info'#010+
   '**1b_generate browser info'#010+
-  '**2bl_generate loc','al symbol info'#010+
+  '**2bl_generate local symbol info'#010+
   '**1B_build all modules'#010+
   '**1B_build all modules'#010+
-  '**1C<x>_code generation options:'#010+
+  '**1C<x>_code generat','ion options:'#010+
   '**2CD_create also dynamic library (not supported)'#010+
   '**2CD_create also dynamic library (not supported)'#010+
   '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
   '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
   '**2Ci_IO-checking'#010+
   '**2Ci_IO-checking'#010+
   '**2Cn_omit linking stage'#010+
   '**2Cn_omit linking stage'#010+
-  '**2Co_check overflow of ','integer operations'#010+
+  '**2Co_check overflow of integer operations'#010+
   '**2Cr_range checking'#010+
   '**2Cr_range checking'#010+
-  '**2Cs<n>_set stack size to <n>'#010+
+  '**2Cs<n>_set stack',' size to <n>'#010+
   '**2Ct_stack checking'#010+
   '**2Ct_stack checking'#010+
   '**2CX_create also smartlinked library'#010+
   '**2CX_create also smartlinked library'#010+
   '**1d<x>_defines the symbol <x>'#010+
   '**1d<x>_defines the symbol <x>'#010+
   '*O1D_generate a DEF file'#010+
   '*O1D_generate a DEF file'#010+
   '*O2Dd<x>_set description to <x>'#010+
   '*O2Dd<x>_set description to <x>'#010+
   '*O2Dw_PM application'#010+
   '*O2Dw_PM application'#010+
-  '*','*1e<x>_set path to executable'#010+
+  '**1e<x>_set path to executable'#010+
   '**1E_same as -Cn'#010+
   '**1E_same as -Cn'#010+
-  '**1F<x>_set file names and paths:'#010+
+  '**1F<x>_set',' file names and paths:'#010+
   '**2FD<x>_sets the directory where to search for compiler utilities'#010+
   '**2FD<x>_sets the directory where to search for compiler utilities'#010+
   '**2Fe<x>_redirect error output to <x>'#010+
   '**2Fe<x>_redirect error output to <x>'#010+
   '**2FE<x>_set exe/unit output path to <x>'#010+
   '**2FE<x>_set exe/unit output path to <x>'#010+
-  '**2Fi<x>_adds',' <x> to include path'#010+
+  '**2Fi<x>_adds <x> to include path'#010+
   '**2Fl<x>_adds <x> to library path'#010+
   '**2Fl<x>_adds <x> to library path'#010+
-  '*L2FL<x>_uses <x> as dynamic linker'#010+
+  '*L2','FL<x>_uses <x> as dynamic linker'#010+
   '**2Fo<x>_adds <x> to object path'#010+
   '**2Fo<x>_adds <x> to object path'#010+
   '**2Fr<x>_load error message file <x>'#010+
   '**2Fr<x>_load error message file <x>'#010+
   '**2Fu<x>_adds <x> to unit path'#010+
   '**2Fu<x>_adds <x> to unit path'#010+
-  '**2FU<x>_set unit output path to <x>, overrides ','-FE'#010+
+  '**2FU<x>_set unit output path to <x>, overrides -FE'#010+
   '*g1g_generate debugger information:'#010+
   '*g1g_generate debugger information:'#010+
   '*g2gg_use gsym'#010+
   '*g2gg_use gsym'#010+
-  '*g2gd_use dbx'#010+
+  '*g2','gd_use dbx'#010+
   '*g2gh_use heap trace unit (for memory leak debugging)'#010+
   '*g2gh_use heap trace unit (for memory leak debugging)'#010+
   '*g2gl_use line info unit to show more info for backtraces'#010+
   '*g2gl_use line info unit to show more info for backtraces'#010+
   '*g2gc_generate checks for pointers'#010+
   '*g2gc_generate checks for pointers'#010+
   '**1i_information'#010+
   '**1i_information'#010+
-  '**2iD_r','eturn compiler date'#010+
+  '**2iD_return compiler date'#010+
   '**2iV_return compiler version'#010+
   '**2iV_return compiler version'#010+
-  '**2iSO_return compiler OS'#010+
+  '**2iSO_r','eturn compiler OS'#010+
   '**2iSP_return compiler processor'#010+
   '**2iSP_return compiler processor'#010+
   '**2iTO_return target OS'#010+
   '**2iTO_return target OS'#010+
   '**2iTP_return target processor'#010+
   '**2iTP_return target processor'#010+
   '**1I<x>_adds <x> to include path'#010+
   '**1I<x>_adds <x> to include path'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1k<x>_Pass <x> to the linker'#010+
-  '**1l_write l','ogo'#010+
+  '**1l_write logo'#010+
   '**1n_don'#039't read the default config file'#010+
   '**1n_don'#039't read the default config file'#010+
-  '**1o<x>_change the name of the executable produced to <x>'#010+
+  '**1o<x>_change',' the name of the executable produced to <x>'#010+
   '**1pg_generate profile code for gprof (defines FPC_PROFILE)'#010+
   '**1pg_generate profile code for gprof (defines FPC_PROFILE)'#010+
   '*L1P_use pipes instead of creating temporary assembler files'#010+
   '*L1P_use pipes instead of creating temporary assembler files'#010+
-  '**1S<x>_syntax op','tions:'#010+
+  '**1S<x>_syntax options:'#010+
   '**2S2_switch some Delphi 2 extensions on'#010+
   '**2S2_switch some Delphi 2 extensions on'#010+
-  '**2Sc_supports operators like C (*=,+=,/= and -=)'#010+
+  '**2Sc_supp','orts operators like C (*=,+=,/= and -=)'#010+
   '**2Sa_include assertion code.'#010+
   '**2Sa_include assertion code.'#010+
   '**2Sd_tries to be Delphi compatible'#010+
   '**2Sd_tries to be Delphi compatible'#010+
   '**2Se<x>_compiler stops after the <x> errors (default is 1)'#010+
   '**2Se<x>_compiler stops after the <x> errors (default is 1)'#010+
-  '**2Sg_allow LABE','L and GOTO'#010+
+  '**2Sg_allow LABEL and GOTO'#010+
   '**2Sh_Use ansistrings'#010+
   '**2Sh_Use ansistrings'#010+
-  '**2Si_support C++ styled INLINE'#010+
+  '**2Si_support C++ styled ','INLINE'#010+
   '**2Sm_support macros like C (global)'#010+
   '**2Sm_support macros like C (global)'#010+
   '**2So_tries to be TP/BP 7.0 compatible'#010+
   '**2So_tries to be TP/BP 7.0 compatible'#010+
   '**2Sp_tries to be gpc compatible'#010+
   '**2Sp_tries to be gpc compatible'#010+
   '**2Ss_constructor name must be init (destructor must be done)'#010+
   '**2Ss_constructor name must be init (destructor must be done)'#010+
-  '**2S','t_allow static keyword in objects'#010+
-  '**1s_don'#039't call assembler and linker (only with -a)'#010+
+  '**2St_allow static keyword in objects'#010+
+  '**1s_don'#039't call assemble','r and linker (only with -a)'#010+
   '**1u<x>_undefines the symbol <x>'#010+
   '**1u<x>_undefines the symbol <x>'#010+
   '**1U_unit options:'#010+
   '**1U_unit options:'#010+
   '**2Un_don'#039't check the unit name'#010+
   '**2Un_don'#039't check the unit name'#010+
   '**2Us_compile a system unit'#010+
   '**2Us_compile a system unit'#010+
-  '**1v<x>_Be verbose. <x> is a combination o','f the following letters:'#010+
-  '**2*_e : Show errors (default)       d : Show debug info'#010+
+  '**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
+  '**2*_e : Show errors (default)   ','    d : Show debug info'#010+
   '**2*_w : Show warnings               u : Show unit info'#010+
   '**2*_w : Show warnings               u : Show unit info'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
-  '**2*_h : Show hints                  m ',': Show defined macros'#010+
-  '**2*_i : Show general info           p : Show compiled procedures'#010+
+  '**2*_h : Show hints                  m : Show defined macros'#010+
+  '**2*_i : Show general info          ',' p : Show compiled procedures'#010+
   '**2*_l : Show linenumbers            c : Show conditionals'#010+
   '**2*_l : Show linenumbers            c : Show conditionals'#010+
   '**2*_a : Show everything             0 : Show nothing (except errors)'#010+
   '**2*_a : Show everything             0 : Show nothing (except errors)'#010+
-  '**2*_b : Show all proce','dure          r : Rhide/GCC compatibility mod'+
-  'e'#010+
-  '**2*_    declarations if an error    x : Executable info (Win32 only)'#010+
+  '**2*_b : Show all procedure          r : Rhide/GCC compatibility mode'#010+
+  '**2*_    de','clarations if an error    x : Executable info (Win32 only'+
+  ')'#010+
   '**2*_    occurs'#010+
   '**2*_    occurs'#010+
   '**1X_executable options:'#010+
   '**1X_executable options:'#010+
   '*L2Xc_link with the c library'#010+
   '*L2Xc_link with the c library'#010+
   '**2Xs_strip all symbols from executable'#010+
   '**2Xs_strip all symbols from executable'#010+
-  '**2XD_try to',' link dynamic          (defines FPC_LINK_DYNAMIC)'#010+
-  '**2XS_try to link static (default) (defines FPC_LINK_STATIC)'#010+
+  '**2XD_try to link dynamic          (defines FPC_LINK_DYNAMIC)'#010+
+  '**2XS_tr','y to link static (default) (defines FPC_LINK_STATIC)'#010+
   '**2XX_try to link smart            (defines FPC_LINK_SMART)'#010+
   '**2XX_try to link smart            (defines FPC_LINK_SMART)'#010+
   '**0*_Processor specific options:'#010+
   '**0*_Processor specific options:'#010+
   '3*1A<x>_output format:'#010+
   '3*1A<x>_output format:'#010+
-  '3*2Aas_assemb','le using GNU AS'#010+
-  '3*2Aasaout_assemble using GNU AS for aout (Go32v1)'#010+
+  '3*2Aas_assemble using GNU AS'#010+
+  '3*2Aasaout_assemble using GNU AS for aout ','(Go32v1)'#010+
   '3*2Anasmcoff_coff (Go32v2) file using Nasm'#010+
   '3*2Anasmcoff_coff (Go32v2) file using Nasm'#010+
   '3*2Anasmelf_elf32 (Linux) file using Nasm'#010+
   '3*2Anasmelf_elf32 (Linux) file using Nasm'#010+
   '3*2Anasmobj_obj file using Nasm'#010+
   '3*2Anasmobj_obj file using Nasm'#010+
   '3*2Amasm_obj file using Masm (Microsoft)'#010+
   '3*2Amasm_obj file using Masm (Microsoft)'#010+
-  '3*2Atasm_obj fi','le using Tasm (Borland)'#010+
-  '3*2Acoff_coff (Go32v2) using internal writer'#010+
+  '3*2Atasm_obj file using Tasm (Borland)'#010+
+  '3*2Acoff_coff (Go32v2) using inter','nal writer'#010+
   '3*2Apecoff_pecoff (Win32) using internal writer'#010+
   '3*2Apecoff_pecoff (Win32) using internal writer'#010+
   '3*1R<x>_assembler reading style:'#010+
   '3*1R<x>_assembler reading style:'#010+
   '3*2Ratt_read AT&T style assembler'#010+
   '3*2Ratt_read AT&T style assembler'#010+
   '3*2Rintel_read Intel style assembler'#010+
   '3*2Rintel_read Intel style assembler'#010+
-  '3*2Rdirect_copy ass','embler text directly to assembler file'#010+
-  '3*1O<x>_optimizations:'#010+
+  '3*2Rdirect_copy assembler text directly to assembler file'#010+
+  '3*1O<x>_optimizatio','ns:'#010+
   '3*2Og_generate smaller code'#010+
   '3*2Og_generate smaller code'#010+
   '3*2OG_generate faster code (default)'#010+
   '3*2OG_generate faster code (default)'#010+
   '3*2Or_keep certain variables in registers'#010+
   '3*2Or_keep certain variables in registers'#010+
   '3*2Ou_enable uncertain optimizations (see docs)'#010+
   '3*2Ou_enable uncertain optimizations (see docs)'#010+
-  '3*2O1_level 1 optimizat','ions (quick optimizations)'#010+
-  '3*2O2_level 2 optimizations (-O1 + slower optimizations)'#010+
+  '3*2O1_level 1 optimizations (quick optimizations)'#010+
+  '3*2O2_level 2 optimizations (-O','1 + slower optimizations)'#010+
   '3*2O3_level 3 optimizations (-O2 repeatedly, max 5 times)'#010+
   '3*2O3_level 3 optimizations (-O2 repeatedly, max 5 times)'#010+
   '3*2Op<x>_target processor:'#010+
   '3*2Op<x>_target processor:'#010+
   '3*3Op1_set target processor to 386/486'#010+
   '3*3Op1_set target processor to 386/486'#010+
-  '3*3Op2_set target processor to P','entium/PentiumMMX (tm)'#010+
-  '3*3Op3_set target processor to PPro/PII/c6x86/K6 (tm)'#010+
+  '3*3Op2_set target processor to Pentium/PentiumMMX (tm)'#010+
+  '3*3Op3_set target processor to PPro','/PII/c6x86/K6 (tm)'#010+
   '3*1T<x>_Target operating system:'#010+
   '3*1T<x>_Target operating system:'#010+
   '3*2TGO32V1_version 1 of DJ Delorie DOS extender'#010+
   '3*2TGO32V1_version 1 of DJ Delorie DOS extender'#010+
   '3*2TGO32V2_version 2 of DJ Delorie DOS extender'#010+
   '3*2TGO32V2_version 2 of DJ Delorie DOS extender'#010+
   '3*2TLINUX_Linux'#010+
   '3*2TLINUX_Linux'#010+
-  '3*2Tnetware_Novell',' Netware Module (experimental)'#010+
+  '3*2Tnetware_Novell Netware Module (experimental)'#010+
   '3*2TOS2_OS/2 2.x'#010+
   '3*2TOS2_OS/2 2.x'#010+
-  '3*2TWin32_Windows 32 Bit'#010+
+  '3*2TWin32_','Windows 32 Bit'#010+
   '3*1W<x>_Win32 target options'#010+
   '3*1W<x>_Win32 target options'#010+
   '3*2WB<x>_Set Image base to Hexadecimal <x> value'#010+
   '3*2WB<x>_Set Image base to Hexadecimal <x> value'#010+
   '3*2WC_Specify console type application'#010+
   '3*2WC_Specify console type application'#010+
-  '3*2WD_Use DEFFILE to export functions of DLL or EX','E'#010+
+  '3*2WD_Use DEFFILE to export functions of DLL or EXE'#010+
   '3*2WG_Specify graphic type application'#010+
   '3*2WG_Specify graphic type application'#010+
-  '3*2WN_Do not generate relocation code (necessary for debugging)'#010+
+  '3*2WN_Do not gene','rate relocation code (necessary for debugging)'#010+
   '3*2WR_Generate relocation code'#010+
   '3*2WR_Generate relocation code'#010+
   '6*1A<x>_output format'#010+
   '6*1A<x>_output format'#010+
   '6*2Aas_Unix o-file using GNU AS'#010+
   '6*2Aas_Unix o-file using GNU AS'#010+
   '6*2Agas_GNU Motorola assembler'#010+
   '6*2Agas_GNU Motorola assembler'#010+
-  '6*2Amit_MIT Syntax ','(old GAS)'#010+
+  '6*2Amit_MIT Syntax (old GAS)'#010+
   '6*2Amot_Standard Motorola assembler'#010+
   '6*2Amot_Standard Motorola assembler'#010+
-  '6*1O_optimizations:'#010+
+  '6*1O_optimiz','ations:'#010+
   '6*2Oa_turn on the optimizer'#010+
   '6*2Oa_turn on the optimizer'#010+
   '6*2Og_generate smaller code'#010+
   '6*2Og_generate smaller code'#010+
   '6*2OG_generate faster code (default)'#010+
   '6*2OG_generate faster code (default)'#010+
   '6*2Ox_optimize maximum (still BUGGY!!!)'#010+
   '6*2Ox_optimize maximum (still BUGGY!!!)'#010+
-  '6*2O2_set target processor to a MC68020+'#010,
+  '6*2O2_set target processor to a MC68020+'#010+
   '6*1R<x>_assembler reading style:'#010+
   '6*1R<x>_assembler reading style:'#010+
-  '6*2RMOT_read motorola style assembler'#010+
+  '6*2RMOT_read motorola sty','le assembler'#010+
   '6*1T<x>_Target operating system:'#010+
   '6*1T<x>_Target operating system:'#010+
   '6*2TAMIGA_Commodore Amiga'#010+
   '6*2TAMIGA_Commodore Amiga'#010+
   '6*2TATARI_Atari ST/STe/TT'#010+
   '6*2TATARI_Atari ST/STe/TT'#010+
@@ -767,5 +779,5 @@ const msgtxt : array[0..000130,1..240] of char=(
   '6*2TLINUX_Linux-68k'#010+
   '6*2TLINUX_Linux-68k'#010+
   '**1*_'#010+
   '**1*_'#010+
   '**1?_shows this help'#010+
   '**1?_shows this help'#010+
-  '**1h_shows t','his help without waiting'#000
+  '**1h_shows this help without waiting'#000
 );
 );

+ 7 - 7
compiler/nadd.pas

@@ -891,8 +891,7 @@ implementation
            end
            end
          else
          else
 
 
-           if (rd^.deftype=objectdef) and (ld^.deftype=objectdef) and
-              pobjectdef(rd)^.is_class and pobjectdef(ld)^.is_class then
+           if is_class_or_interface(rd) and is_class_or_interface(ld) then
             begin
             begin
               location.loc:=LOC_REGISTER;
               location.loc:=LOC_REGISTER;
               if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
               if pobjectdef(rd)^.is_related(pobjectdef(ld)) then
@@ -930,8 +929,7 @@ implementation
          else
          else
 
 
          { allows comperasion with nil pointer }
          { allows comperasion with nil pointer }
-           if (rd^.deftype=objectdef) and
-              pobjectdef(rd)^.is_class then
+           if is_class_or_interface(rd) then
             begin
             begin
               location.loc:=LOC_REGISTER;
               location.loc:=LOC_REGISTER;
               left:=gentypeconvnode(left,rd);
               left:=gentypeconvnode(left,rd);
@@ -945,8 +943,7 @@ implementation
             end
             end
          else
          else
 
 
-           if (ld^.deftype=objectdef) and
-              pobjectdef(ld)^.is_class then
+           if is_class_or_interface(ld) then
             begin
             begin
               location.loc:=LOC_REGISTER;
               location.loc:=LOC_REGISTER;
               right:=gentypeconvnode(right,ld);
               right:=gentypeconvnode(right,ld);
@@ -1232,7 +1229,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.14  2000-10-31 22:02:47  peter
+  Revision 1.15  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.14  2000/10/31 22:02:47  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.13  2000/10/14 10:14:50  peter
   Revision 1.13  2000/10/14 10:14:50  peter

+ 11 - 8
compiler/ncal.pas

@@ -261,11 +261,11 @@ interface
               if do_count then
               if do_count then
                begin
                begin
                  { not completly proper, but avoids some warnings }
                  { not completly proper, but avoids some warnings }
-                 if (defcoll^.paratyp=vs_var) then
+                 if (defcoll^.paratyp in [vs_var,vs_out]) then
                    set_funcret_is_valid(left);
                    set_funcret_is_valid(left);
 
 
                  { protected has nothing to do with read/write
                  { protected has nothing to do with read/write
-                 if (defcoll^.paratyp=vs_var) then
+                 if (defcoll^.paratyp in [vs_var,vs_out]) then
                    test_protected(left);
                    test_protected(left);
                  }
                  }
                  { set_varstate(left,defcoll^.paratyp<>vs_var);
                  { set_varstate(left,defcoll^.paratyp<>vs_var);
@@ -367,13 +367,13 @@ interface
                     CGMessage(type_e_strict_var_string_violation);
                     CGMessage(type_e_strict_var_string_violation);
                  end;
                  end;
 
 
-              { Variablen for call by reference may not be copied }
+              { variabls for call by reference may not be copied }
               { into a register }
               { into a register }
               { is this usefull here ? }
               { is this usefull here ? }
               { this was missing in formal parameter list   }
               { this was missing in formal parameter list   }
               if (defcoll^.paratype.def=pdef(cformaldef)) then
               if (defcoll^.paratype.def=pdef(cformaldef)) then
                 begin
                 begin
-                  if defcoll^.paratyp=vs_var then
+                  if defcoll^.paratyp in [vs_var,vs_out] then
                     begin
                     begin
                       if not valid_for_formal_var(left) then
                       if not valid_for_formal_var(left) then
                         begin
                         begin
@@ -406,7 +406,7 @@ interface
                 make_not_regable(left);
                 make_not_regable(left);
 
 
               if do_count then
               if do_count then
-                set_varstate(left,defcoll^.paratyp <> vs_var);
+                set_varstate(left,defcoll^.paratyp in [vs_var,vs_out]);
                 { must only be done after typeconv PM }
                 { must only be done after typeconv PM }
               resulttype:=defcoll^.paratype.def;
               resulttype:=defcoll^.paratype.def;
            end;
            end;
@@ -802,7 +802,7 @@ interface
                          (m_tp_procvar in aktmodeswitches) then
                          (m_tp_procvar in aktmodeswitches) then
                         begin
                         begin
                           if (symtableprocentry^.owner^.symtabletype=objectsymtable) and
                           if (symtableprocentry^.owner^.symtabletype=objectsymtable) and
-                             (pobjectdef(symtableprocentry^.owner^.defowner)^.is_class) then
+                             is_class(pdef(symtableprocentry^.owner^.defowner)) then
                            hpt:=genloadmethodcallnode(pprocsym(symtableprocentry),symtableproc,
                            hpt:=genloadmethodcallnode(pprocsym(symtableprocentry),symtableproc,
                                  methodpointer.getcopy)
                                  methodpointer.getcopy)
                           else
                           else
@@ -856,7 +856,7 @@ interface
                                begin
                                begin
                                  hp^.nextpara^.argconvtyp:=act_convertable;
                                  hp^.nextpara^.argconvtyp:=act_convertable;
                                  hp^.nextpara^.convertlevel:=isconvertable(pt.resulttype,hp^.nextpara^.paratype.def,
                                  hp^.nextpara^.convertlevel:=isconvertable(pt.resulttype,hp^.nextpara^.paratype.def,
-                                     hcvt,pt.left.nodetype,false);
+                                     hcvt,pt.left,pt.left.nodetype,false);
                                  case hp^.nextpara^.convertlevel of
                                  case hp^.nextpara^.convertlevel of
                                   1 : include(pt.callparaflags,cpf_convlevel1found);
                                   1 : include(pt.callparaflags,cpf_convlevel1found);
                                   2 : include(pt.callparaflags,cpf_convlevel2found);
                                   2 : include(pt.callparaflags,cpf_convlevel2found);
@@ -1545,7 +1545,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.13  2000-10-31 22:02:47  peter
+  Revision 1.14  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.13  2000/10/31 22:02:47  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.12  2000/10/21 18:16:11  florian
   Revision 1.12  2000/10/21 18:16:11  florian

+ 15 - 10
compiler/ncnv.pas

@@ -726,7 +726,9 @@ implementation
            @ttypeconvnode.first_proc_to_procvar,
            @ttypeconvnode.first_proc_to_procvar,
            @ttypeconvnode.first_arrayconstructor_to_set,
            @ttypeconvnode.first_arrayconstructor_to_set,
            @ttypeconvnode.first_load_smallset,
            @ttypeconvnode.first_load_smallset,
-           @ttypeconvnode.first_cord_to_pointer
+           @ttypeconvnode.first_cord_to_pointer,
+           @ttypeconvnode.first_nothing,
+           @ttypeconvnode.first_nothing
          );
          );
       type
       type
          tprocedureofobject = function : tnode of object;
          tprocedureofobject = function : tnode of object;
@@ -823,7 +825,7 @@ implementation
             exit;
             exit;
          end;
          end;
 
 
-       if isconvertable(left.resulttype,resulttype,convtype,left.nodetype,nf_explizit in flags)=0 then
+       if isconvertable(left.resulttype,resulttype,convtype,left,left.nodetype,nf_explizit in flags)=0 then
          begin
          begin
            {Procedures have a resulttype of voiddef and functions of their
            {Procedures have a resulttype of voiddef and functions of their
            own resulttype. They will therefore always be incompatible with
            own resulttype. They will therefore always be incompatible with
@@ -935,7 +937,7 @@ implementation
                   end
                   end
                  else
                  else
                   begin
                   begin
-                    if isconvertable(s32bitdef,resulttype,convtype,ordconstn,false)=0 then
+                    if isconvertable(s32bitdef,resulttype,convtype,nil,ordconstn,false)=0 then
                       CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                       CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                   end;
                   end;
                end
                end
@@ -954,7 +956,7 @@ implementation
                    end
                    end
                   else
                   else
                    begin
                    begin
-                     if IsConvertable(left.resulttype,s32bitdef,convtype,ordconstn,false)=0 then
+                     if IsConvertable(left.resulttype,s32bitdef,convtype,nil,ordconstn,false)=0 then
                        CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                        CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                    end;
                    end;
                 end
                 end
@@ -983,7 +985,7 @@ implementation
                     end
                     end
                    else
                    else
                     begin
                     begin
-                      if IsConvertable(left.resulttype,u8bitdef,convtype,ordconstn,false)=0 then
+                      if IsConvertable(left.resulttype,u8bitdef,convtype,nil,ordconstn,false)=0 then
                         CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                         CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                     end;
                     end;
                  end
                  end
@@ -1002,7 +1004,7 @@ implementation
                     end
                     end
                    else
                    else
                     begin
                     begin
-                      if IsConvertable(u8bitdef,resulttype,convtype,ordconstn,false)=0 then
+                      if IsConvertable(u8bitdef,resulttype,convtype,nil,ordconstn,false)=0 then
                         CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                         CGMessage2(type_e_incompatible_types,left.resulttype^.typename,resulttype^.typename);
                     end;
                     end;
                  end
                  end
@@ -1029,7 +1031,7 @@ implementation
                { the conversion into a strutured type is only }
                { the conversion into a strutured type is only }
                { possible, if the source is no register    }
                { possible, if the source is no register    }
                if ((resulttype^.deftype in [recorddef,stringdef,arraydef]) or
                if ((resulttype^.deftype in [recorddef,stringdef,arraydef]) or
-                   ((resulttype^.deftype=objectdef) and not(pobjectdef(resulttype)^.is_class))
+                   ((resulttype^.deftype=objectdef) and not(is_class(resulttype)))
                   ) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
                   ) and (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) { and
                    it also works if the assignment is overloaded
                    it also works if the assignment is overloaded
                    YES but this code is not executed if assignment is overloaded (PM)
                    YES but this code is not executed if assignment is overloaded (PM)
@@ -1099,7 +1101,7 @@ implementation
 
 
          { left must be a class }
          { left must be a class }
          if (left.resulttype^.deftype<>objectdef) or
          if (left.resulttype^.deftype<>objectdef) or
-            not(pobjectdef(left.resulttype)^.is_class) then
+            not(is_class(left.resulttype)) then
            CGMessage(type_e_mismatch);
            CGMessage(type_e_mismatch);
 
 
          { the operands must be related }
          { the operands must be related }
@@ -1141,7 +1143,7 @@ implementation
 
 
          { left must be a class }
          { left must be a class }
          if (left.resulttype^.deftype<>objectdef) or
          if (left.resulttype^.deftype<>objectdef) or
-           not(pobjectdef(left.resulttype)^.is_class) then
+           not(is_class(left.resulttype)) then
            CGMessage(type_e_mismatch);
            CGMessage(type_e_mismatch);
 
 
          { the operands must be related }
          { the operands must be related }
@@ -1163,7 +1165,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2000-10-31 22:02:48  peter
+  Revision 1.10  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.9  2000/10/31 22:02:48  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.8  2000/10/14 21:52:55  peter
   Revision 1.8  2000/10/14 21:52:55  peter

+ 6 - 5
compiler/nflw.pas

@@ -746,8 +746,7 @@ implementation
               { first para must be a _class_ }
               { first para must be a _class_ }
               firstpass(left);
               firstpass(left);
               if assigned(left.resulttype) and
               if assigned(left.resulttype) and
-                 ((left.resulttype^.deftype<>objectdef) or
-                  not(pobjectdef(left.resulttype)^.is_class)) then
+                 not(is_class(left.resulttype)) then
                 CGMessage(type_e_mismatch);
                 CGMessage(type_e_mismatch);
               set_varstate(left,true);
               set_varstate(left,true);
               if codegenerror then
               if codegenerror then
@@ -919,8 +918,7 @@ implementation
       begin
       begin
          pass_1:=nil;
          pass_1:=nil;
          { that's really an example procedure for a firstpass :) }
          { that's really an example procedure for a firstpass :) }
-         if (excepttype^.deftype<>objectdef) or
-           not(pobjectdef(excepttype)^.is_class) then
+         if not(is_class(excepttype)) then
            CGMessage(type_e_mismatch);
            CGMessage(type_e_mismatch);
 {$ifdef newcg}
 {$ifdef newcg}
          tg.cleartempgen;
          tg.cleartempgen;
@@ -994,7 +992,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2000-10-31 22:02:48  peter
+  Revision 1.10  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.9  2000/10/31 22:02:48  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.8  2000/10/21 18:16:11  florian
   Revision 1.8  2000/10/21 18:16:11  florian

+ 4 - 10
compiler/nld.pas

@@ -287,15 +287,6 @@ implementation
 
 
                    if ([vo_is_thread_var,vo_is_dll_var]*pvarsym(symtableentry)^.varoptions)<>[] then
                    if ([vo_is_thread_var,vo_is_dll_var]*pvarsym(symtableentry)^.varoptions)<>[] then
                      registers32:=1;
                      registers32:=1;
-                   { a class variable is a pointer !!!
-                     yes, but we have to resolve the reference in an
-                     appropriate tree node (FK)
-
-                   if (pvarsym(symtableentry)^.definition^.deftype=objectdef) and
-                      ((pobjectdef(pvarsym(symtableentry)^.definition)^.options and oo_is_class)<>0) then
-                     registers32:=1;
-                   }
-
                    { count variable references }
                    { count variable references }
 
 
                      { this will create problem with local var set by
                      { this will create problem with local var set by
@@ -752,7 +743,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2000-10-31 22:02:49  peter
+  Revision 1.8  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.7  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.6  2000/10/14 10:14:50  peter
   Revision 1.6  2000/10/14 10:14:50  peter

+ 8 - 8
compiler/nmem.pas

@@ -403,7 +403,7 @@ implementation
 
 
                      { method ? then set the methodpointer flag }
                      { method ? then set the methodpointer flag }
                        if (hp3^.owner^.symtabletype=objectsymtable) and
                        if (hp3^.owner^.symtabletype=objectsymtable) and
-                          (pobjectdef(hp3^.owner^.defowner)^.is_class) then
+                          is_class(pdef(hp3^.owner^.defowner)) then
                          include(pprocvardef(resulttype)^.procoptions,po_methodpointer);
                          include(pprocvardef(resulttype)^.procoptions,po_methodpointer);
                        { we need to process the parameters reverse so they are inserted
                        { we need to process the parameters reverse so they are inserted
                          in the correct right2left order (PFV) }
                          in the correct right2left order (PFV) }
@@ -596,8 +596,7 @@ implementation
          registersmmx:=left.registersmmx;
          registersmmx:=left.registersmmx;
 {$endif SUPPORT_MMX}
 {$endif SUPPORT_MMX}
          { classes must be dereferenced implicit }
          { classes must be dereferenced implicit }
-         if (left.resulttype^.deftype=objectdef) and
-           pobjectdef(left.resulttype)^.is_class then
+         if is_class_or_interface(left.resulttype) then
            begin
            begin
               if registers32=0 then
               if registers32=0 then
                 registers32:=1;
                 registers32:=1;
@@ -641,7 +640,7 @@ implementation
          if (left.resulttype^.deftype=arraydef) then
          if (left.resulttype^.deftype=arraydef) then
            begin
            begin
               if (isconvertable(right.resulttype,parraydef(left.resulttype)^.rangetype.def,
               if (isconvertable(right.resulttype,parraydef(left.resulttype)^.rangetype.def,
-                    ct,ordconstn,false)=0) and
+                    ct,nil,ordconstn,false)=0) and
                  not(is_equal(right.resulttype,parraydef(left.resulttype)^.rangetype.def)) then
                  not(is_equal(right.resulttype,parraydef(left.resulttype)^.rangetype.def)) then
                 CGMessage(type_e_mismatch);
                 CGMessage(type_e_mismatch);
            end;
            end;
@@ -778,9 +777,7 @@ implementation
       begin
       begin
          pass_1:=nil;
          pass_1:=nil;
          if (resulttype^.deftype=classrefdef) or
          if (resulttype^.deftype=classrefdef) or
-           ((resulttype^.deftype=objectdef)
-             and pobjectdef(resulttype)^.is_class
-           ) then
+           is_class(resulttype) then
            location.loc:=LOC_CREGISTER
            location.loc:=LOC_CREGISTER
          else
          else
            location.loc:=LOC_REFERENCE;
            location.loc:=LOC_REFERENCE;
@@ -872,7 +869,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2000-10-31 22:02:49  peter
+  Revision 1.10  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.9  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.8  2000/10/21 18:16:11  florian
   Revision 1.8  2000/10/21 18:16:11  florian

+ 5 - 2
compiler/nset.pas

@@ -305,7 +305,7 @@ implementation
            exit;
            exit;
          { both types must be compatible }
          { both types must be compatible }
          if not(is_equal(left.resulttype,right.resulttype)) and
          if not(is_equal(left.resulttype,right.resulttype)) and
-            (isconvertable(left.resulttype,right.resulttype,ct,ordconstn,false)=0) then
+            (isconvertable(left.resulttype,right.resulttype,ct,nil,ordconstn,false)=0) then
            CGMessage(type_e_mismatch);
            CGMessage(type_e_mismatch);
          { Check if only when its a constant set }
          { Check if only when its a constant set }
          if (left.nodetype=ordconstn) and (right.nodetype=ordconstn) then
          if (left.nodetype=ordconstn) and (right.nodetype=ordconstn) then
@@ -525,7 +525,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2000-10-31 22:02:49  peter
+  Revision 1.8  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.7  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.6  2000/10/21 18:16:11  florian
   Revision 1.6  2000/10/21 18:16:11  florian

+ 37 - 27
compiler/options.pas

@@ -703,28 +703,38 @@ begin
 {$endif}
 {$endif}
               's' : initglobalswitches:=initglobalswitches+[cs_asm_extern,cs_link_extern];
               's' : initglobalswitches:=initglobalswitches+[cs_asm_extern,cs_link_extern];
               'S' : begin
               'S' : begin
-                      for j:=1 to length(more) do
-                       case more[j] of
-                        '2' : SetCompileMode('OBJFPC',true);
-                        'a' : initlocalswitches:=InitLocalswitches+[cs_do_assertion];
-                        'c' : initmoduleswitches:=initmoduleswitches+[cs_support_c_operators];
-                        'd' : SetCompileMode('DELPHI',true);
-                        'e' : begin
-                                SetErrorFlags(more);
-                                break;
-                              end;
-                        'g' : initmoduleswitches:=initmoduleswitches+[cs_support_goto];
-                        'h' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
-                        'i' : initmoduleswitches:=initmoduleswitches+[cs_support_inline];
-                        'm' : initmoduleswitches:=initmoduleswitches+[cs_support_macro];
-                        'o' : SetCompileMode('TP',true);
-                        'p' : SetCompileMode('GPC',true);
-                        's' : initglobalswitches:=initglobalswitches+[cs_constructor_name];
-                        't' : initmoduleswitches:=initmoduleswitches+[cs_static_keyword];
-                        'v' : Message1(option_obsolete_switch,'-Sv');
-                       else
-                        IllegalPara(opt);
-                       end;
+                      if more[1]='I' then
+                        begin
+                          if upper(more)='ICOM' then
+                            initinterfacetype:=it_interfacecom
+                          else if upper(more)='ICORBA' then
+                            initinterfacetype:=it_interfacecorba
+                          else
+                            IllegalPara(opt);
+                        end
+                      else
+                        for j:=1 to length(more) do
+                         case more[j] of
+                          '2' : SetCompileMode('OBJFPC',true);
+                          'a' : initlocalswitches:=InitLocalswitches+[cs_do_assertion];
+                          'c' : initmoduleswitches:=initmoduleswitches+[cs_support_c_operators];
+                          'd' : SetCompileMode('DELPHI',true);
+                          'e' : begin
+                                  SetErrorFlags(more);
+                                  break;
+                                end;
+                          'g' : initmoduleswitches:=initmoduleswitches+[cs_support_goto];
+                          'h' : initlocalswitches:=initlocalswitches+[cs_ansistrings];
+                          'i' : initmoduleswitches:=initmoduleswitches+[cs_support_inline];
+                          'm' : initmoduleswitches:=initmoduleswitches+[cs_support_macro];
+                          'o' : SetCompileMode('TP',true);
+                          'p' : SetCompileMode('GPC',true);
+                          's' : initglobalswitches:=initglobalswitches+[cs_constructor_name];
+                          't' : initmoduleswitches:=initmoduleswitches+[cs_static_keyword];
+                          'v' : Message1(option_obsolete_switch,'-Sv');
+                         else
+                          IllegalPara(opt);
+                         end;
                     end;
                     end;
               'T' : begin
               'T' : begin
                       more:=Upper(More);
                       more:=Upper(More);
@@ -1181,9 +1191,6 @@ procedure read_arguments(cmd:string);
 var
 var
   configpath : pathstr;
   configpath : pathstr;
 begin
 begin
-{$ifdef Delphi}
-  option:=new(poption386,Init);
-{$endif Delphi}
 {$ifdef i386}
 {$ifdef i386}
   option:=new(poption386,Init);
   option:=new(poption386,Init);
 {$endif}
 {$endif}
@@ -1490,7 +1497,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2000-09-26 10:50:41  jonas
+  Revision 1.12  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.11  2000/09/26 10:50:41  jonas
     * initmodeswitches is changed is you change the compiler mode from the
     * initmodeswitches is changed is you change the compiler mode from the
       command line (the -S<x> switches didn't work anymore for changing the
       command line (the -S<x> switches didn't work anymore for changing the
       compiler mode) (merged from fixes branch)
       compiler mode) (merged from fixes branch)
@@ -1527,4 +1537,4 @@ end.
   Revision 1.2  2000/07/13 11:32:44  michael
   Revision 1.2  2000/07/13 11:32:44  michael
   + removed logs
   + removed logs
 
 
-}
+}

+ 10 - 1
compiler/parser.pas

@@ -258,12 +258,15 @@ implementation
          oldaktspecificoptprocessor,
          oldaktspecificoptprocessor,
          oldaktoptprocessor : tprocessors;
          oldaktoptprocessor : tprocessors;
          oldaktasmmode      : tasmmode;
          oldaktasmmode      : tasmmode;
+         oldaktinterfacetype: tinterfacetypes;
          oldaktmodeswitches : tmodeswitches;
          oldaktmodeswitches : tmodeswitches;
          old_compiled_module : pmodule;
          old_compiled_module : pmodule;
          prev_name          : pstring;
          prev_name          : pstring;
 {$ifdef USEEXCEPT}
 {$ifdef USEEXCEPT}
+{$ifndef Delphi}
          recoverpos    : jmp_buf;
          recoverpos    : jmp_buf;
          oldrecoverpos : pjmp_buf;
          oldrecoverpos : pjmp_buf;
+{$endif Delphi}         
 {$endif useexcept}
 {$endif useexcept}
 {$ifdef newcg}
 {$ifdef newcg}
          oldcg         : pcg;
          oldcg         : pcg;
@@ -327,6 +330,7 @@ implementation
          oldaktoptprocessor:=aktoptprocessor;
          oldaktoptprocessor:=aktoptprocessor;
          oldaktspecificoptprocessor:=aktspecificoptprocessor;
          oldaktspecificoptprocessor:=aktspecificoptprocessor;
          oldaktasmmode:=aktasmmode;
          oldaktasmmode:=aktasmmode;
+         oldaktinterfacetype:=aktinterfacetype;
          oldaktfilepos:=aktfilepos;
          oldaktfilepos:=aktfilepos;
          oldaktmodeswitches:=aktmodeswitches;
          oldaktmodeswitches:=aktmodeswitches;
 {$ifdef newcg}
 {$ifdef newcg}
@@ -381,6 +385,7 @@ implementation
          aktoptprocessor:=initoptprocessor;
          aktoptprocessor:=initoptprocessor;
          aktspecificoptprocessor:=initspecificoptprocessor;
          aktspecificoptprocessor:=initspecificoptprocessor;
          aktasmmode:=initasmmode;
          aktasmmode:=initasmmode;
+         aktinterfacetype:=initinterfacetype;
          { we need this to make the system unit }
          { we need this to make the system unit }
          if compile_system then
          if compile_system then
           aktmoduleswitches:=aktmoduleswitches+[cs_compilesystem];
           aktmoduleswitches:=aktmoduleswitches+[cs_compilesystem];
@@ -516,6 +521,7 @@ implementation
               aktoptprocessor:=oldaktoptprocessor;
               aktoptprocessor:=oldaktoptprocessor;
               aktspecificoptprocessor:=oldaktspecificoptprocessor;
               aktspecificoptprocessor:=oldaktspecificoptprocessor;
               aktasmmode:=oldaktasmmode;
               aktasmmode:=oldaktasmmode;
+              aktinterfacetype:=oldaktinterfacetype;
               aktfilepos:=oldaktfilepos;
               aktfilepos:=oldaktfilepos;
               aktmodeswitches:=oldaktmodeswitches;
               aktmodeswitches:=oldaktmodeswitches;
            end;
            end;
@@ -587,7 +593,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.8  2000-10-31 22:02:49  peter
+  Revision 1.9  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.8  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.7  2000/10/14 10:14:51  peter
   Revision 1.7  2000/10/14 10:14:51  peter

+ 12 - 5
compiler/pdecl.pas

@@ -312,6 +312,7 @@ implementation
                     akttokenpos:=stpos;
                     akttokenpos:=stpos;
                     { we don't need the forwarddef anymore, dispose it }
                     { we don't need the forwarddef anymore, dispose it }
                     dispose(hpd,done);
                     dispose(hpd,done);
+                    ppointerdef(pd)^.pointertype.def:=nil; { if error occurs }
                     { was a type sym found ? }
                     { was a type sym found ? }
                     if assigned(srsym) and
                     if assigned(srsym) and
                        (srsym^.typ=typesym) then
                        (srsym^.typ=typesym) then
@@ -329,8 +330,7 @@ implementation
 {$endif GDB}
 {$endif GDB}
                        { we need a class type for classrefdef }
                        { we need a class type for classrefdef }
                        if (pd^.deftype=classrefdef) and
                        if (pd^.deftype=classrefdef) and
-                          not((ptypesym(srsym)^.restype.def^.deftype=objectdef) and
-                              pobjectdef(ptypesym(srsym)^.restype.def)^.is_class) then
+                          not(is_class(ptypesym(srsym)^.restype.def)) then
                          Message1(type_e_class_type_expected,ptypesym(srsym)^.restype.def^.typename);
                          Message1(type_e_class_type_expected,ptypesym(srsym)^.restype.def^.typename);
                      end
                      end
                     else
                     else
@@ -400,8 +400,7 @@ implementation
                begin
                begin
                  if (token=_CLASS) and
                  if (token=_CLASS) and
                     (assigned(ptypesym(sym)^.restype.def)) and
                     (assigned(ptypesym(sym)^.restype.def)) and
-                    (ptypesym(sym)^.restype.def^.deftype=objectdef) and
-                    pobjectdef(ptypesym(sym)^.restype.def)^.is_class and
+                    is_class(ptypesym(sym)^.restype.def) and
                     (oo_is_forward in pobjectdef(ptypesym(sym)^.restype.def)^.objectoptions) then
                     (oo_is_forward in pobjectdef(ptypesym(sym)^.restype.def)^.objectoptions) then
                   begin
                   begin
                     { we can ignore the result   }
                     { we can ignore the result   }
@@ -431,6 +430,11 @@ implementation
                 tt.sym:=newtype;
                 tt.sym:=newtype;
               if assigned(tt.def) and not assigned(tt.def^.typesym) then
               if assigned(tt.def) and not assigned(tt.def^.typesym) then
                 tt.def^.typesym:=newtype;
                 tt.def^.typesym:=newtype;
+              { KAZ: handle TGUID declaration in system unit }
+              if (cs_compilesystem in aktmoduleswitches) and not assigned(rec_tguid) and
+                 (typename='TGUID') and { name: TGUID and size=16 bytes that is 128 bits }
+                 assigned(tt.def) and (tt.def^.deftype=recorddef) and (tt.def^.size=16) then
+                rec_tguid:=precorddef(tt.def);
             end;
             end;
            if assigned(newtype^.restype.def) and
            if assigned(newtype^.restype.def) and
               (newtype^.restype.def^.deftype=procvardef) then
               (newtype^.restype.def^.deftype=procvardef) then
@@ -528,7 +532,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.18  2000-10-31 22:02:49  peter
+  Revision 1.19  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.18  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.17  2000/10/14 10:14:51  peter
   Revision 1.17  2000/10/14 10:14:51  peter

+ 143 - 62
compiler/pdecobj.pas

@@ -51,7 +51,7 @@ implementation
       var
       var
          actmembertype : tsymoptions;
          actmembertype : tsymoptions;
          there_is_a_destructor : boolean;
          there_is_a_destructor : boolean;
-         classtype : (ct_object,ct_class,ct_interfacecom,ct_interfaceraw,ct_cppclass);
+         classtype : tobjectdeftype;
          childof : pobjectdef;
          childof : pobjectdef;
          aktclass : pobjectdef;
          aktclass : pobjectdef;
 
 
@@ -70,7 +70,7 @@ implementation
            include(aktclass^.objectoptions,oo_has_constructor);
            include(aktclass^.objectoptions,oo_has_constructor);
            consume(_SEMICOLON);
            consume(_SEMICOLON);
              begin
              begin
-                if (aktclass^.is_class) then
+                if is_class(aktclass) then
                   begin
                   begin
                      { CLASS constructors return the created instance }
                      { CLASS constructors return the created instance }
                      aktprocsym^.definition^.rettype.def:=aktclass;
                      aktprocsym^.definition^.rettype.def:=aktclass;
@@ -124,7 +124,7 @@ implementation
 
 
         begin
         begin
            { check for a class }
            { check for a class }
-           if not(aktclass^.is_class) then
+           if not(is_class(aktclass)) then
             Message(parser_e_syntax_error);
             Message(parser_e_syntax_error);
            consume(_PROPERTY);
            consume(_PROPERTY);
            new(propertyparas,init);
            new(propertyparas,init);
@@ -544,9 +544,9 @@ implementation
       procedure setclassattributes;
       procedure setclassattributes;
 
 
         begin
         begin
-           if classtype=ct_class then
+           if classtype=odt_class then
              begin
              begin
-                include(aktclass^.objectoptions,oo_is_class);
+                aktclass^.objecttype:=odt_class;
                 if (cs_generate_rtti in aktlocalswitches) or
                 if (cs_generate_rtti in aktlocalswitches) or
                     (assigned(aktclass^.childof) and
                     (assigned(aktclass^.childof) and
                      (oo_can_have_published in aktclass^.childof^.objectoptions)) then
                      (oo_can_have_published in aktclass^.childof^.objectoptions)) then
@@ -563,35 +563,27 @@ implementation
      procedure setclassparent;
      procedure setclassparent;
 
 
         begin
         begin
+           if assigned(fd) then
+             aktclass:=fd
+           else
+             aktclass:=new(pobjectdef,init(classtype,n,nil));
            { is the current class tobject?   }
            { is the current class tobject?   }
            { so you could define your own tobject }
            { so you could define your own tobject }
-           if (cs_compilesystem in aktmoduleswitches) and
-              (upper(n)='TOBJECT') then
-             begin
-                if assigned(fd) then
-                  aktclass:=fd
-                else
-                  aktclass:=new(pobjectdef,init(n,nil));
-                class_tobject:=aktclass;
-             end
+           if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_class) and (n='TOBJECT') then
+             class_tobject:=aktclass
+           else if (cs_compilesystem in aktmoduleswitches) and (classtype=odt_interfacecom) and (n='IUNKNOWN') then
+             interface_iunknown:=aktclass
            else
            else
              begin
              begin
-                childof:=class_tobject;
-                if assigned(fd) then
-                  begin
-                     { the forward of the child must be resolved to get
-                       correct field addresses
-                     }
-                     if (oo_is_forward in childof^.objectoptions) then
-                       Message1(parser_e_forward_declaration_must_be_resolved,childof^.objname^);
-                     aktclass:=fd;
-                     aktclass^.set_parent(childof);
-                  end
-                else
-                  begin
-                     aktclass:=new(pobjectdef,init(n,childof));
-                     aktclass^.set_parent(childof);
-                  end;
+                case classtype of
+                  odt_class:
+                    childof:=class_tobject;
+                  odt_interfacecom:
+                    childof:=interface_iunknown;
+                end;
+                if (oo_is_forward in childof^.objectoptions) then
+                  Message1(parser_e_forward_declaration_must_be_resolved,childof^.objname^);
+                aktclass^.set_parent(childof);
              end;
              end;
          end;
          end;
 
 
@@ -603,6 +595,7 @@ implementation
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
            dmtlabel : pasmlabel;
            dmtlabel : pasmlabel;
 {$endif WITHDMT}
 {$endif WITHDMT}
+           interfacetable : pasmlabel;
 
 
         begin
         begin
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
@@ -614,7 +607,7 @@ implementation
 
 
            { write tables for classes, this must be done before the actual
            { write tables for classes, this must be done before the actual
              class is written, because we need the labels defined }
              class is written, because we need the labels defined }
-           if classtype=ct_class then
+           if classtype=odt_class then
             begin
             begin
               methodnametable:=genpublishedmethodstable(aktclass);
               methodnametable:=genpublishedmethodstable(aktclass);
               fieldtablelabel:=aktclass^.generate_field_table;
               fieldtablelabel:=aktclass^.generate_field_table;
@@ -633,6 +626,8 @@ implementation
                 intmessagetable:=genintmsgtab(aktclass)
                 intmessagetable:=genintmsgtab(aktclass)
               else
               else
                 datasegment^.concat(new(pai_const,init_32bit(0)));
                 datasegment^.concat(new(pai_const,init_32bit(0)));
+              if aktclass^.implementedinterfaces^.count>0 then
+                interfacetable:=genintftable(aktclass);
             end;
             end;
 
 
           { write debug info }
           { write debug info }
@@ -671,7 +666,7 @@ implementation
              datasegment^.concat(new(pai_const,init_32bit(0)));
              datasegment^.concat(new(pai_const,init_32bit(0)));
 
 
            { write extended info for classes, for the order see rtl/inc/objpash.inc }
            { write extended info for classes, for the order see rtl/inc/objpash.inc }
-           if classtype=ct_class then
+           if classtype=odt_class then
             begin
             begin
               { pointer to class name string }
               { pointer to class name string }
               datasegment^.concat(new(pai_const_symbol,init(classnamelabel)));
               datasegment^.concat(new(pai_const_symbol,init(classnamelabel)));
@@ -706,7 +701,10 @@ implementation
               { auto table }
               { auto table }
               datasegment^.concat(new(pai_const,init_32bit(0)));
               datasegment^.concat(new(pai_const,init_32bit(0)));
               { interface table }
               { interface table }
-              datasegment^.concat(new(pai_const,init_32bit(0)));
+              if aktclass^.implementedinterfaces^.count>0 then
+                datasegment^.concat(new(pai_const_symbol,init(interfacetable)))
+              else
+                datasegment^.concat(new(pai_const,init_32bit(0)));
               { table for string messages }
               { table for string messages }
               if (oo_has_msgstr in aktclass^.objectoptions) then
               if (oo_has_msgstr in aktclass^.objectoptions) then
                 datasegment^.concat(new(pai_const_symbol,init(strmessagetable)))
                 datasegment^.concat(new(pai_const_symbol,init(strmessagetable)))
@@ -719,6 +717,28 @@ implementation
            datasegment^.concat(new(pai_symbol_end,initname(aktclass^.vmt_mangledname)));
            datasegment^.concat(new(pai_symbol_end,initname(aktclass^.vmt_mangledname)));
         end;
         end;
 
 
+      procedure setinterfacemethodoptions;
+
+        var
+          i: longint;
+          defs: pindexarray;
+          pd: pprocdef;
+        begin
+          include(aktclass^.objectoptions,oo_has_virtual);
+          defs:=aktclass^.symtable^.defindex;
+          for i:=1 to defs^.count do
+            begin
+              pd:=pprocdef(defs^.search(i));
+              if pd^.deftype=procdef then
+                begin
+                  pd^.extnumber:=aktclass^.lastvtableindex;
+                  aktclass^.lastvtableindex:=aktclass^.lastvtableindex+1;
+                  include(pd^.procoptions,po_virtualmethod);
+                  pd^.forwarddef:=false;
+                end;
+            end;
+        end;
+
       function readobjecttype : boolean;
       function readobjecttype : boolean;
 
 
         begin
         begin
@@ -727,21 +747,21 @@ implementation
            case token of
            case token of
               _OBJECT:
               _OBJECT:
                 begin
                 begin
-                   classtype:=ct_object;
+                   classtype:=odt_object;
                    consume(_OBJECT)
                    consume(_OBJECT)
                 end;
                 end;
               _CPPCLASS:
               _CPPCLASS:
                 begin
                 begin
-                   classtype:=ct_cppclass;
+                   classtype:=odt_cppclass;
                    consume(_CPPCLASS);
                    consume(_CPPCLASS);
                 end;
                 end;
 {$ifdef SUPPORT_INTERFACE}
 {$ifdef SUPPORT_INTERFACE}
               _INTERFACE:
               _INTERFACE:
                 begin
                 begin
                    if aktinterfacetype=it_interfacecom then
                    if aktinterfacetype=it_interfacecom then
-                     objecttype:=ct_interfacecom
-                   else {it_interfaceraw}
-                     objecttype:=ct_interfaceraw;
+                     objecttype:=odt_interfacecom
+                   else {it_interfacecorba}
+                     objecttype:=odt_interfacecorba;
                    consume(_INTERFACE);
                    consume(_INTERFACE);
                    { forward declaration }
                    { forward declaration }
                    if not(assigned(fd)) and (token=_SEMICOLON) then
                    if not(assigned(fd)) and (token=_SEMICOLON) then
@@ -753,13 +773,13 @@ implementation
                        if (cs_compilesystem in aktmoduleswitches) and
                        if (cs_compilesystem in aktmoduleswitches) and
                           (objecttype=odt_interfacecom) and (n='IUNKNOWN') then
                           (objecttype=odt_interfacecom) and (n='IUNKNOWN') then
                          interface_iunknown:=aktclass;
                          interface_iunknown:=aktclass;
-                       include(aktclass^.objectoptions,[oo_is_forward]);
+                       aktclass^.objectoptions:=aktclass^.objectoptions+[oo_is_forward];
                      end;
                      end;
                 end;
                 end;
 {$endif SUPPORT_INTERFACE}
 {$endif SUPPORT_INTERFACE}
               _CLASS:
               _CLASS:
                 begin
                 begin
-                   classtype:=ct_class;
+                   classtype:=odt_class;
                    consume(_CLASS);
                    consume(_CLASS);
                    if not(assigned(fd)) and (token=_OF) then
                    if not(assigned(fd)) and (token=_OF) then
                      begin
                      begin
@@ -770,7 +790,7 @@ implementation
 
 
                         { accept hp1, if is a forward def or a class }
                         { accept hp1, if is a forward def or a class }
                         if (tt.def^.deftype=forwarddef) or
                         if (tt.def^.deftype=forwarddef) or
-                           ((tt.def^.deftype=objectdef) and pobjectdef(tt.def)^.is_class) then
+                           is_class(tt.def) then
                           begin
                           begin
                              pcrd:=new(pclassrefdef,init(tt.def));
                              pcrd:=new(pclassrefdef,init(tt.def));
                              object_dec:=pcrd;
                              object_dec:=pcrd;
@@ -790,10 +810,11 @@ implementation
                         { also anonym objects aren't allow (o : object a : longint; end;) }
                         { also anonym objects aren't allow (o : object a : longint; end;) }
                         if n='' then
                         if n='' then
                           Message(parser_f_no_anonym_objects);
                           Message(parser_f_no_anonym_objects);
-                        aktclass:=new(pobjectdef,init(n,nil));
+                        aktclass:=new(pobjectdef,init(odt_class,n,nil));
                         if (cs_compilesystem in aktmoduleswitches) and (n='TOBJECT') then
                         if (cs_compilesystem in aktmoduleswitches) and (n='TOBJECT') then
                           class_tobject:=aktclass;
                           class_tobject:=aktclass;
-                        aktclass^.objectoptions:=aktclass^.objectoptions+[oo_is_class,oo_is_forward];
+                        aktclass^.objecttype:=odt_class;
+                        include(aktclass^.objectoptions,oo_is_forward);
                         { all classes must have a vmt !!  at offset zero }
                         { all classes must have a vmt !!  at offset zero }
                         if not(oo_has_vmt in aktclass^.objectoptions) then
                         if not(oo_has_vmt in aktclass^.objectoptions) then
                           aktclass^.insertvmt;
                           aktclass^.insertvmt;
@@ -806,12 +827,35 @@ implementation
                 end;
                 end;
               else
               else
                 begin
                 begin
-                   classtype:=ct_class; { this is error but try to recover }
+                   classtype:=odt_class; { this is error but try to recover }
                    consume(_OBJECT);
                    consume(_OBJECT);
                 end;
                 end;
            end;
            end;
         end;
         end;
 
 
+      procedure readimplementedinterfaces;
+        var
+          implintf: pobjectdef;
+          tt      : ttype;
+        begin
+          while try_to_consume(_COMMA) do begin
+            id_type(tt,pattern,false);
+            implintf:=pobjectdef(tt.def);
+            if (tt.def^.deftype<>objectdef) then begin
+              Message1(type_e_interface_type_expected,tt.def^.typename);
+              Continue; { omit }
+            end;
+            if not is_interface(implintf) then begin
+              Message1(type_e_interface_type_expected,implintf^.typename);
+              Continue; { omit }
+            end;
+            if aktclass^.implementedinterfaces^.searchintf(tt.def)<>-1 then
+              Message1(sym_e_duplicate_id,tt.def^.name)
+            else
+              aktclass^.implementedinterfaces^.addintf(tt.def);
+          end;
+        end;
+
       procedure readparentclasses;
       procedure readparentclasses;
 
 
         begin
         begin
@@ -828,26 +872,26 @@ implementation
                    if assigned(childof) then
                    if assigned(childof) then
                     Message1(type_e_class_type_expected,childof^.typename);
                     Message1(type_e_class_type_expected,childof^.typename);
                    childof:=nil;
                    childof:=nil;
-                   aktclass:=new(pobjectdef,init(n,nil));
+                   aktclass:=new(pobjectdef,init(classtype,n,nil));
                  end
                  end
                 else
                 else
                  begin
                  begin
                    { a mix of class, interfaces, objects and cppclasses
                    { a mix of class, interfaces, objects and cppclasses
                      isn't allowed }
                      isn't allowed }
                    case classtype of
                    case classtype of
-                      ct_class:
-                        if not(childof^.is_class) and
-                          not(childof^.is_interface) then
+                      odt_class:
+                        if not(is_class(childof)) and
+                          not(is_interface(childof)) then
                           Message(parser_e_mix_of_classes_and_objects);
                           Message(parser_e_mix_of_classes_and_objects);
-                      ct_interfaceraw,
-                      ct_interfacecom:
-                        if not(childof^.is_interface) then
+                      odt_interfacecorba,
+                      odt_interfacecom:
+                        if not(is_interface(childof)) then
                           Message(parser_e_mix_of_classes_and_objects);
                           Message(parser_e_mix_of_classes_and_objects);
-                      ct_cppclass:
-                        if not(childof^.is_cppclass) then
+                      odt_cppclass:
+                        if not(is_cppclass(childof)) then
                           Message(parser_e_mix_of_classes_and_objects);
                           Message(parser_e_mix_of_classes_and_objects);
-                      ct_object:
-                        if not(childof^.is_object) then
+                      odt_object:
+                        if not(is_object(childof)) then
                           Message(parser_e_mix_of_classes_and_objects);
                           Message(parser_e_mix_of_classes_and_objects);
                    end;
                    end;
                    { the forward of the child must be resolved to get
                    { the forward of the child must be resolved to get
@@ -864,21 +908,23 @@ implementation
                       fd^.set_parent(childof);
                       fd^.set_parent(childof);
                     end
                     end
                    else
                    else
-                    aktclass:=new(pobjectdef,init(n,childof));
+                    aktclass:=new(pobjectdef,init(classtype,n,childof));
+                   if aktclass^.objecttype=odt_class then
+                    readimplementedinterfaces;
                  end;
                  end;
                 consume(_RKLAMMER);
                 consume(_RKLAMMER);
              end
              end
            { if no parent class, then a class get tobject as parent }
            { if no parent class, then a class get tobject as parent }
-           else if classtype=ct_class then
+           else if classtype=odt_class then
              setclassparent
              setclassparent
            else
            else
-             aktclass:=new(pobjectdef,init(n,nil));
+             aktclass:=new(pobjectdef,init(classtype,n,nil));
         end;
         end;
 
 
       procedure chkcpp;
       procedure chkcpp;
 
 
         begin
         begin
-           if aktclass^.is_cppclass then
+           if is_cppclass(aktclass) then
              begin
              begin
                 include(aktprocsym^.definition^.proccalloptions,pocall_cppdecl);
                 include(aktprocsym^.definition^.proccalloptions,pocall_cppdecl);
                 aktprocsym^.definition^.setmangledname(
                 aktprocsym^.definition^.setmangledname(
@@ -886,6 +932,30 @@ implementation
              end;
              end;
         end;
         end;
 
 
+      procedure readinterfaceiid;
+        var
+          tt: ttype;
+          p : tnode;
+          isiidguidvalid: boolean;
+
+        begin
+          p:=comp_expr(true);
+          do_firstpass(p);
+          if p.nodetype=stringconstn then
+            begin
+              aktclass^.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
+              p.free;
+              aktclass^.isiidguidvalid:=string2guid(aktclass^.iidstr^,aktclass^.iidguid);
+              if (classtype=odt_interfacecom) and not aktclass^.isiidguidvalid then
+                Message(parser_e_improper_guid_syntax);
+            end
+          else
+            begin
+              p.free;
+              Message(cg_e_illegal_expression);
+            end;
+        end;
+
       var
       var
         temppd : pprocdef;
         temppd : pprocdef;
       begin
       begin
@@ -938,7 +1008,7 @@ implementation
 
 
 
 
        { short class declaration ? }
        { short class declaration ? }
-         if (classtype<>ct_class) or (token<>_SEMICOLON) then
+         if (classtype<>odt_class) or (token<>_SEMICOLON) then
           begin
           begin
           { Parse componenten }
           { Parse componenten }
             repeat
             repeat
@@ -1051,14 +1121,22 @@ implementation
 
 
          { generate vmt space if needed }
          { generate vmt space if needed }
          if not(oo_has_vmt in aktclass^.objectoptions) and
          if not(oo_has_vmt in aktclass^.objectoptions) and
-            ([oo_has_virtual,oo_has_constructor,oo_has_destructor,oo_is_class]*aktclass^.objectoptions<>[]) then
+            (([oo_has_virtual,oo_has_constructor,oo_has_destructor]*aktclass^.objectoptions<>[]) or
+             (classtype=odt_class)
+            ) then
            aktclass^.insertvmt;
            aktclass^.insertvmt;
          if (cs_create_smart in aktmoduleswitches) then
          if (cs_create_smart in aktmoduleswitches) then
            datasegment^.concat(new(pai_cut,init));
            datasegment^.concat(new(pai_cut,init));
 
 
+         if is_interface(aktclass) then
+           writeinterfaceids(aktclass);
+
          if (oo_has_vmt in aktclass^.objectoptions) then
          if (oo_has_vmt in aktclass^.objectoptions) then
            writevmt;
            writevmt;
 
 
+         if is_interface(aktclass) then
+           setinterfacemethodoptions;
+
          { restore old state }
          { restore old state }
          symtablestack:=symtablestack^.next;
          symtablestack:=symtablestack^.next;
          aktobjectdef:=nil;
          aktobjectdef:=nil;
@@ -1074,7 +1152,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2000-10-31 22:02:49  peter
+  Revision 1.5  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.4  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.3  2000/10/26 21:54:03  peter
   Revision 1.3  2000/10/26 21:54:03  peter

+ 83 - 34
compiler/pdecsub.pas

@@ -37,6 +37,7 @@ interface
       pd_object    = $10;   { directive can be used object declaration }
       pd_object    = $10;   { directive can be used object declaration }
       pd_procvar   = $20;   { directive can be used procvar declaration }
       pd_procvar   = $20;   { directive can be used procvar declaration }
       pd_notobject = $40;   { directive can not be used object declaration }
       pd_notobject = $40;   { directive can not be used object declaration }
+      pd_notobjintf= $80;   { directive can not be used interface declaration }
 
 
     function  is_proc_directive(tok:ttoken):boolean;
     function  is_proc_directive(tok:ttoken):boolean;
     function  check_identical_proc(var p : pprocdef) : boolean;
     function  check_identical_proc(var p : pprocdef) : boolean;
@@ -130,7 +131,7 @@ implementation
           { self is only allowed in procvars and class methods }
           { self is only allowed in procvars and class methods }
           if (idtoken=_SELF) and
           if (idtoken=_SELF) and
              (is_procvar or
              (is_procvar or
-              (assigned(procinfo^._class) and procinfo^._class^.is_class)) then
+              (assigned(procinfo^._class) and is_class(procinfo^._class))) then
             begin
             begin
               if not is_procvar then
               if not is_procvar then
                begin
                begin
@@ -318,6 +319,7 @@ var orgsp,sp:stringid;
     st : psymtable;
     st : psymtable;
     overloaded_level:word;
     overloaded_level:word;
     storepos,procstartfilepos : tfileposinfo;
     storepos,procstartfilepos : tfileposinfo;
+    i: longint;
 begin
 begin
 { Save the position where this procedure really starts and set col to 1 which
 { Save the position where this procedure really starts and set col to 1 which
   looks nicer }
   looks nicer }
@@ -337,7 +339,44 @@ begin
       consume(_ID);
       consume(_ID);
     end;
     end;
 
 
-{ method ? }
+    { examine interface map: function/procedure iname.functionname=locfuncname }
+    if parse_only and assigned(procinfo^._class) and
+       assigned(procinfo^._class^.implementedinterfaces) and
+       (procinfo^._class^.implementedinterfaces^.count>0) and
+       try_to_consume(_POINT) then
+      begin
+         storepos:=akttokenpos;
+         akttokenpos:=procstartfilepos;
+         { get interface syms}
+         getsym(sp,true);
+         sym:=srsym;
+         akttokenpos:=storepos;
+         { load proc name }
+         sp:=pattern;
+         if sym^.typ=typesym then
+           i:=procinfo^._class^.implementedinterfaces^.searchintf(ptypesym(sym)^.restype.def);
+         { qualifier is interface name? }
+         if (sym^.typ<>typesym) or (ptypesym(sym)^.restype.def^.deftype<>objectdef) or
+            (i=-1) then
+           begin
+              Message(parser_e_interface_id_expected);
+              aktprocsym:=nil;
+           end
+         else
+           begin
+              aktprocsym:=pprocsym(procinfo^._class^.implementedinterfaces^.interfaces(i)^.symtable^.search(sp));
+              if not(assigned(aktprocsym)) then
+                Message(parser_e_methode_id_expected);
+           end;
+         consume(_ID);
+         consume(_EQUAL);
+         if (token=_ID) and assigned(aktprocsym) then
+           procinfo^._class^.implementedinterfaces^.addmappings(i,sp,pattern);
+         consume(_ID);
+         exit;
+    end;
+
+  { method  ? }
   if not(parse_only) and
   if not(parse_only) and
      (lexlevel=normal_function_level) and
      (lexlevel=normal_function_level) and
      try_to_consume(_POINT) then
      try_to_consume(_POINT) then
@@ -508,7 +547,7 @@ begin
     end;
     end;
 
 
   if assigned (procinfo^._Class)  and
   if assigned (procinfo^._Class)  and
-     not(procinfo^._Class^.is_class) and
+     is_object(procinfo^._Class) and
      (pd^.proctypeoption in [potype_constructor,potype_destructor]) then
      (pd^.proctypeoption in [potype_constructor,potype_destructor]) then
     inc(paramoffset,target_os.size_of_pointer);
     inc(paramoffset,target_os.size_of_pointer);
 
 
@@ -524,7 +563,7 @@ begin
 
 
   { con/-destructor flag ? }
   { con/-destructor flag ? }
   if assigned (procinfo^._Class) and
   if assigned (procinfo^._Class) and
-     procinfo^._class^.is_class and
+     is_class(procinfo^._class) and
      (pd^.proctypeoption in [potype_destructor,potype_constructor]) then
      (pd^.proctypeoption in [potype_destructor,potype_constructor]) then
     inc(paramoffset,target_os.size_of_pointer);
     inc(paramoffset,target_os.size_of_pointer);
 
 
@@ -592,7 +631,8 @@ begin
                    parse_proc_head(potype_none);
                    parse_proc_head(potype_none);
                    if token<>_COLON then
                    if token<>_COLON then
                     begin
                     begin
-                       if not(aktprocsym^.definition^.forwarddef) or
+                       if not(is_interface(aktprocsym^.definition^._class)) and
+                          not(aktprocsym^.definition^.forwarddef) or
                          (m_repeat_forward in aktmodeswitches) then
                          (m_repeat_forward in aktmodeswitches) then
                        begin
                        begin
                          consume(_COLON);
                          consume(_COLON);
@@ -617,7 +657,7 @@ begin
                    consume(_CONSTRUCTOR);
                    consume(_CONSTRUCTOR);
                    parse_proc_head(potype_constructor);
                    parse_proc_head(potype_constructor);
                    if assigned(procinfo^._class) and
                    if assigned(procinfo^._class) and
-                      procinfo^._class^.is_class then
+                      is_class(procinfo^._class) then
                     begin
                     begin
                       { CLASS constructors return the created instance }
                       { CLASS constructors return the created instance }
                       aktprocsym^.definition^.rettype.def:=procinfo^._class;
                       aktprocsym^.definition^.rettype.def:=procinfo^._class;
@@ -804,10 +844,10 @@ var
 {$endif WITHDMT}
 {$endif WITHDMT}
 begin
 begin
   if (aktprocsym^.definition^.proctypeoption=potype_constructor) and
   if (aktprocsym^.definition^.proctypeoption=potype_constructor) and
-     not(aktprocsym^.definition^._class^.is_class) then
+     is_object(aktprocsym^.definition^._class) then
     Message(parser_e_constructor_cannot_be_not_virtual);
     Message(parser_e_constructor_cannot_be_not_virtual);
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
-  if not(aktprocsym^.definition^._class^.is_class) and
+  if is_object(aktprocsym^.definition^._class) and
     (token<>_SEMICOLON) then
     (token<>_SEMICOLON) then
     begin
     begin
        { any type of parameter is allowed here! }
        { any type of parameter is allowed here! }
@@ -837,7 +877,7 @@ end;
 
 
 procedure pd_override(const procnames:Tstringcontainer);
 procedure pd_override(const procnames:Tstringcontainer);
 begin
 begin
-  if not(aktprocsym^.definition^._class^.is_class) then
+  if not(is_class_or_interface(aktprocsym^.definition^._class)) then
     Message(parser_e_no_object_override);
     Message(parser_e_no_object_override);
 end;
 end;
 
 
@@ -1043,7 +1083,7 @@ const
    (
    (
     (
     (
       idtok:_ABSTRACT;
       idtok:_ABSTRACT;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_abstract;
       pocall   : [];
       pocall   : [];
       pooption : [po_abstractmethod];
       pooption : [po_abstractmethod];
@@ -1052,7 +1092,7 @@ const
       mutexclpo     : [po_exports,po_interrupt,po_external]
       mutexclpo     : [po_exports,po_interrupt,po_external]
     ),(
     ),(
       idtok:_ALIAS;
       idtok:_ALIAS;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_alias;
       pocall   : [];
       pocall   : [];
       pooption : [];
       pooption : [];
@@ -1061,7 +1101,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_ASMNAME;
       idtok:_ASMNAME;
-      pd_flags : pd_interface+pd_implemen;
+      pd_flags : pd_interface+pd_implemen+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_asmname;
       pocall   : [pocall_cdecl,pocall_clearstack];
       pocall   : [pocall_cdecl,pocall_clearstack];
       pooption : [po_external];
       pooption : [po_external];
@@ -1070,7 +1110,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_ASSEMBLER;
       idtok:_ASSEMBLER;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : nil;
       handler  : nil;
       pocall   : [];
       pocall   : [];
       pooption : [po_assembler];
       pooption : [po_assembler];
@@ -1088,7 +1128,7 @@ const
       mutexclpo     : [po_assembler,po_external]
       mutexclpo     : [po_assembler,po_external]
     ),(
     ),(
       idtok:_DYNAMIC;
       idtok:_DYNAMIC;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
       pocall   : [];
       pocall   : [];
       pooption : [po_virtualmethod];
       pooption : [po_virtualmethod];
@@ -1097,7 +1137,7 @@ const
       mutexclpo     : [po_exports,po_interrupt,po_external]
       mutexclpo     : [po_exports,po_interrupt,po_external]
     ),(
     ),(
       idtok:_EXPORT;
       idtok:_EXPORT;
-      pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??};
+      pd_flags : pd_body+pd_global+pd_interface+pd_implemen{??}+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_export;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_export;
       pocall   : [];
       pocall   : [];
       pooption : [po_exports];
       pooption : [po_exports];
@@ -1106,7 +1146,7 @@ const
       mutexclpo     : [po_external,po_interrupt]
       mutexclpo     : [po_external,po_interrupt]
     ),(
     ),(
       idtok:_EXTERNAL;
       idtok:_EXTERNAL;
-      pd_flags : pd_implemen+pd_interface;
+      pd_flags : pd_implemen+pd_interface+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_external;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_external;
       pocall   : [];
       pocall   : [];
       pooption : [po_external];
       pooption : [po_external];
@@ -1115,7 +1155,7 @@ const
       mutexclpo     : [po_exports,po_interrupt,po_assembler]
       mutexclpo     : [po_exports,po_interrupt,po_assembler]
     ),(
     ),(
       idtok:_FAR;
       idtok:_FAR;
-      pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar;
+      pd_flags : pd_implemen+pd_body+pd_interface+pd_procvar+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_far;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_far;
       pocall   : [];
       pocall   : [];
       pooption : [];
       pooption : [];
@@ -1124,7 +1164,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_FORWARD;
       idtok:_FORWARD;
-      pd_flags : pd_implemen;
+      pd_flags : pd_implemen+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_forward;
       pocall   : [];
       pocall   : [];
       pooption : [];
       pooption : [];
@@ -1133,7 +1173,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_INLINE;
       idtok:_INLINE;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_inline;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_inline;
       pocall   : [pocall_inline];
       pocall   : [pocall_inline];
       pooption : [];
       pooption : [];
@@ -1142,7 +1182,7 @@ const
       mutexclpo     : [po_exports,po_external,po_interrupt]
       mutexclpo     : [po_exports,po_external,po_interrupt]
     ),(
     ),(
       idtok:_INTERNCONST;
       idtok:_INTERNCONST;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
       pocall   : [pocall_internconst];
       pocall   : [pocall_internconst];
       pooption : [];
       pooption : [];
@@ -1151,7 +1191,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_INTERNPROC;
       idtok:_INTERNPROC;
-      pd_flags : pd_implemen;
+      pd_flags : pd_implemen+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_intern;
       pocall   : [pocall_internproc];
       pocall   : [pocall_internproc];
       pooption : [];
       pooption : [];
@@ -1160,7 +1200,7 @@ const
       mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck]
       mutexclpo     : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck]
     ),(
     ),(
       idtok:_INTERRUPT;
       idtok:_INTERRUPT;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt;
       pocall   : [];
       pocall   : [];
       pooption : [po_interrupt];
       pooption : [po_interrupt];
@@ -1169,7 +1209,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_IOCHECK;
       idtok:_IOCHECK;
-      pd_flags : pd_implemen+pd_body;
+      pd_flags : pd_implemen+pd_body+pd_notobjintf;
       handler  : nil;
       handler  : nil;
       pocall   : [];
       pocall   : [];
       pooption : [po_iocheck];
       pooption : [po_iocheck];
@@ -1178,7 +1218,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_MESSAGE;
       idtok:_MESSAGE;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_message;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_message;
       pocall   : [];
       pocall   : [];
       pooption : []; { can be po_msgstr or po_msgint }
       pooption : []; { can be po_msgstr or po_msgint }
@@ -1187,7 +1227,7 @@ const
       mutexclpo     : [po_interrupt,po_external]
       mutexclpo     : [po_interrupt,po_external]
     ),(
     ),(
       idtok:_NEAR;
       idtok:_NEAR;
-      pd_flags : pd_implemen+pd_body+pd_procvar;
+      pd_flags : pd_implemen+pd_body+pd_procvar+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_near;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_near;
       pocall   : [];
       pocall   : [];
       pooption : [];
       pooption : [];
@@ -1205,7 +1245,7 @@ const
       mutexclpo     : []
       mutexclpo     : []
     ),(
     ),(
       idtok:_OVERRIDE;
       idtok:_OVERRIDE;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_override;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_override;
       pocall   : [];
       pocall   : [];
       pooption : [po_overridingmethod,po_virtualmethod];
       pooption : [po_overridingmethod,po_virtualmethod];
@@ -1232,7 +1272,7 @@ const
       mutexclpo     : [po_assembler,po_external]
       mutexclpo     : [po_assembler,po_external]
     ),(
     ),(
       idtok:_PUBLIC;
       idtok:_PUBLIC;
-      pd_flags : pd_implemen+pd_body+pd_global+pd_notobject;
+      pd_flags : pd_implemen+pd_body+pd_global+pd_notobject+pd_notobjintf;
       handler  : nil;
       handler  : nil;
       pocall   : [];
       pocall   : [];
       pooption : [];
       pooption : [];
@@ -1268,7 +1308,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_SAVEREGISTERS;
       idtok:_SAVEREGISTERS;
-      pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar;
+      pd_flags : pd_interface+pd_implemen+pd_body+pd_procvar+pd_notobjintf;
       handler  : nil;
       handler  : nil;
       pocall   : [];
       pocall   : [];
       pooption : [po_saveregisters];
       pooption : [po_saveregisters];
@@ -1277,7 +1317,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_STATIC;
       idtok:_STATIC;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_static;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_static;
       pocall   : [];
       pocall   : [];
       pooption : [po_staticmethod];
       pooption : [po_staticmethod];
@@ -1295,7 +1335,7 @@ const
       mutexclpo     : [po_external]
       mutexclpo     : [po_external]
     ),(
     ),(
       idtok:_SYSCALL;
       idtok:_SYSCALL;
-      pd_flags : pd_interface;
+      pd_flags : pd_interface+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_syscall;
       pocall   : [pocall_palmossyscall];
       pocall   : [pocall_palmossyscall];
       pooption : [];
       pooption : [];
@@ -1304,7 +1344,7 @@ const
       mutexclpo     : [po_external,po_assembler,po_interrupt,po_exports]
       mutexclpo     : [po_external,po_assembler,po_interrupt,po_exports]
     ),(
     ),(
       idtok:_SYSTEM;
       idtok:_SYSTEM;
-      pd_flags : pd_implemen;
+      pd_flags : pd_implemen+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_system;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_system;
       pocall   : [pocall_clearstack];
       pocall   : [pocall_clearstack];
       pooption : [];
       pooption : [];
@@ -1313,7 +1353,7 @@ const
       mutexclpo     : [po_external,po_assembler,po_interrupt]
       mutexclpo     : [po_external,po_assembler,po_interrupt]
     ),(
     ),(
       idtok:_VIRTUAL;
       idtok:_VIRTUAL;
-      pd_flags : pd_interface+pd_object;
+      pd_flags : pd_interface+pd_object+pd_notobjintf;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
       handler  : {$ifdef FPCPROCVAR}@{$endif}pd_virtual;
       pocall   : [];
       pocall   : [];
       pooption : [po_virtualmethod];
       pooption : [po_virtualmethod];
@@ -1402,6 +1442,13 @@ begin
       exit;
       exit;
     end;
     end;
 
 
+{ check if method and directive not for interface }
+  if ((proc_direcdata[p].pd_flags and pd_notobjintf)<>0) and
+     is_interface(aktprocsym^.definition^._class) then
+    begin
+      exit;
+    end;
+
 { consume directive, and turn flag on }
 { consume directive, and turn flag on }
   consume(token);
   consume(token);
   parse_proc_direc:=true;
   parse_proc_direc:=true;
@@ -1815,7 +1862,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.5  2000-11-01 23:04:37  peter
+  Revision 1.6  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.5  2000/11/01 23:04:37  peter
     * tprocdef.fullprocname added for better casesensitve writing of
     * tprocdef.fullprocname added for better casesensitve writing of
       procedures
       procedures
 
 
@@ -1834,5 +1884,4 @@ end.
 
 
   Revision 1.1  2000/10/14 10:14:51  peter
   Revision 1.1  2000/10/14 10:14:51  peter
     * moehrendorf oct 2000 rewrite
     * moehrendorf oct 2000 rewrite
-
 }
 }

+ 5 - 2
compiler/pdecvar.pas

@@ -422,7 +422,7 @@ implementation
                begin
                begin
                   { save object option, because we can turn of the sp_published }
                   { save object option, because we can turn of the sp_published }
                   if (sp_published in current_object_option) and
                   if (sp_published in current_object_option) and
-                    (not((tt.def^.deftype=objectdef) and (pobjectdef(tt.def)^.is_class))) then
+                    not(is_class(tt.def)) then
                    begin
                    begin
                      Message(parser_e_cant_publish_that);
                      Message(parser_e_cant_publish_that);
                      exclude(current_object_option,sp_published);
                      exclude(current_object_option,sp_published);
@@ -527,7 +527,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2000-10-31 22:02:49  peter
+  Revision 1.3  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.2  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.1  2000/10/14 10:14:51  peter
   Revision 1.1  2000/10/14 10:14:51  peter

+ 9 - 8
compiler/pexpr.pas

@@ -368,7 +368,7 @@ implementation
                    procvardef,
                    procvardef,
                    classrefdef : ;
                    classrefdef : ;
                    objectdef :
                    objectdef :
-                     if not(pobjectdef(p1.resulttype)^.is_class) then
+                     if not is_class_or_interface(p1.resulttype) then
                        Message(parser_e_illegal_parameter_list);
                        Message(parser_e_illegal_parameter_list);
                    else
                    else
                      Message(parser_e_illegal_parameter_list);
                      Message(parser_e_illegal_parameter_list);
@@ -1191,10 +1191,9 @@ implementation
                                        p1:=gentypeconvnode(p1,pd);
                                        p1:=gentypeconvnode(p1,pd);
                                        include(p1.flags,nf_explizit);
                                        include(p1.flags,nf_explizit);
                                      end
                                      end
-                                    else { not LKLAMMER}
+                                    else { not LKLAMMER }
                                      if (token=_POINT) and
                                      if (token=_POINT) and
-                                        (pd^.deftype=objectdef) and
-                                        not(pobjectdef(pd)^.is_class) then
+                                        is_object(pd) then
                                        begin
                                        begin
                                          consume(_POINT);
                                          consume(_POINT);
                                          if assigned(procinfo) and
                                          if assigned(procinfo) and
@@ -1246,8 +1245,7 @@ implementation
                                      else
                                      else
                                        begin
                                        begin
                                           { class reference ? }
                                           { class reference ? }
-                                          if (pd^.deftype=objectdef)
-                                            and pobjectdef(pd)^.is_class then
+                                          if is_object(pd) then
                                             begin
                                             begin
                                                if getaddr and (token=_POINT) then
                                                if getaddr and (token=_POINT) then
                                                  begin
                                                  begin
@@ -1540,7 +1538,7 @@ implementation
 
 
                _LECKKLAMMER:
                _LECKKLAMMER:
                   begin
                   begin
-                    if (pd^.deftype=objectdef) and pobjectdef(pd)^.is_class then
+                    if is_class_or_interface(pd) then
                       begin
                       begin
                         { default property }
                         { default property }
                         propsym:=search_default_property(pobjectdef(pd));
                         propsym:=search_default_property(pobjectdef(pd));
@@ -2374,7 +2372,10 @@ _LECKKLAMMER : begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.14  2000-10-31 22:02:49  peter
+  Revision 1.15  2000-11-04 14:25:20  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.14  2000/10/31 22:02:49  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.13  2000/10/26 23:40:54  peter
   Revision 1.13  2000/10/26 23:40:54  peter

+ 7 - 6
compiler/pstatmnt.pas

@@ -596,8 +596,7 @@ implementation
                                     consume(_ID);
                                     consume(_ID);
                                  end;
                                  end;
                                if (srsym^.typ=typesym) and
                                if (srsym^.typ=typesym) and
-                                 (ptypesym(srsym)^.restype.def^.deftype=objectdef) and
-                                 pobjectdef(ptypesym(srsym)^.restype.def)^.is_class then
+                                  is_class(ptypesym(srsym)^.restype.def) then
                                  begin
                                  begin
                                     ot:=pobjectdef(ptypesym(srsym)^.restype.def);
                                     ot:=pobjectdef(ptypesym(srsym)^.restype.def);
                                     sym:=new(pvarsym,initdef(objname,ot));
                                     sym:=new(pvarsym,initdef(objname,ot));
@@ -633,8 +632,7 @@ implementation
                                     consume(_ID);
                                     consume(_ID);
                                  end;
                                  end;
                                if (srsym^.typ=typesym) and
                                if (srsym^.typ=typesym) and
-                                 (ptypesym(srsym)^.restype.def^.deftype=objectdef) and
-                                 pobjectdef(ptypesym(srsym)^.restype.def)^.is_class then
+                                  is_class(ptypesym(srsym)^.restype.def) then
                                  ot:=pobjectdef(ptypesym(srsym)^.restype.def)
                                  ot:=pobjectdef(ptypesym(srsym)^.restype.def)
                                else
                                else
                                  begin
                                  begin
@@ -893,7 +891,7 @@ implementation
               end;
               end;
             { check, if the first parameter is a pointer to a _class_ }
             { check, if the first parameter is a pointer to a _class_ }
             classh:=pobjectdef(ppointerdef(pd)^.pointertype.def);
             classh:=pobjectdef(ppointerdef(pd)^.pointertype.def);
-            if classh^.is_class then
+            if is_class(classh) then
               begin
               begin
                  Message(parser_e_no_new_or_dispose_for_classes);
                  Message(parser_e_no_new_or_dispose_for_classes);
                  new_dispose_statement:=factor(false);
                  new_dispose_statement:=factor(false);
@@ -1258,7 +1256,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.12  2000-10-31 22:02:50  peter
+  Revision 1.13  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.12  2000/10/31 22:02:50  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.11  2000/10/14 21:52:56  peter
   Revision 1.11  2000/10/14 21:52:56  peter

+ 80 - 43
compiler/ptconst.pas

@@ -76,6 +76,7 @@ implementation
          ll        : pasmlabel;
          ll        : pasmlabel;
          s         : string;
          s         : string;
          ca        : pchar;
          ca        : pchar;
+         tmpguid   : tguid;
          aktpos    : longint;
          aktpos    : longint;
          obj       : pobjectdef;
          obj       : pobjectdef;
          symt      : psymtable;
          symt      : psymtable;
@@ -600,7 +601,7 @@ implementation
               if p.nodetype=calln then
               if p.nodetype=calln then
                begin
                begin
                  if (tcallnode(p).symtableprocentry^.owner^.symtabletype=objectsymtable) and
                  if (tcallnode(p).symtableprocentry^.owner^.symtabletype=objectsymtable) and
-                    (pobjectdef(tcallnode(p).symtableprocentry^.owner^.defowner)^.is_class) then
+                    is_class(pdef(tcallnode(p).symtableprocentry^.owner^.defowner)) then
                   hp:=genloadmethodcallnode(pprocsym(tcallnode(p).symtableprocentry),tcallnode(p).symtableproc,
                   hp:=genloadmethodcallnode(pprocsym(tcallnode(p).symtableprocentry),tcallnode(p).symtableproc,
                         tcallnode(p).methodpointer.getcopy)
                         tcallnode(p).methodpointer.getcopy)
                  else
                  else
@@ -618,9 +619,9 @@ implementation
                 (taddrnode(p).left.nodetype=calln) then
                 (taddrnode(p).left.nodetype=calln) then
                 begin
                 begin
                    if (tcallnode(taddrnode(p).left).symtableprocentry^.owner^.symtabletype=objectsymtable) and
                    if (tcallnode(taddrnode(p).left).symtableprocentry^.owner^.symtabletype=objectsymtable) and
-                      (pobjectdef(tcallnode(taddrnode(p).left).symtableprocentry^.owner^.defowner)^.is_class) then
+                      is_class(pdef(tcallnode(taddrnode(p).left).symtableprocentry^.owner^.defowner)) then
                     hp:=genloadmethodcallnode(pprocsym(tcallnode(taddrnode(p).left).symtableprocentry),
                     hp:=genloadmethodcallnode(pprocsym(tcallnode(taddrnode(p).left).symtableprocentry),
-                    tcallnode(taddrnode(p).left).symtableproc,tcallnode(taddrnode(p).left).methodpointer.getcopy)
+                      tcallnode(taddrnode(p).left).symtableproc,tcallnode(taddrnode(p).left).methodpointer.getcopy)
                    else
                    else
                     hp:=genloadcallnode(pprocsym(tcallnode(taddrnode(p).left).symtableprocentry),
                     hp:=genloadcallnode(pprocsym(tcallnode(taddrnode(p).left).symtableprocentry),
                       tcallnode(taddrnode(p).left).symtableproc);
                       tcallnode(taddrnode(p).left).symtableproc);
@@ -672,62 +673,95 @@ implementation
          { reads a typed constant record }
          { reads a typed constant record }
          recorddef:
          recorddef:
            begin
            begin
-              consume(_LKLAMMER);
-              aktpos:=0;
-              while token<>_RKLAMMER do
+              { KAZ }
+              if (precorddef(def)=rec_tguid) and
+                 ((token=_CSTRING) or (token=_CCHAR) or (token=_ID)) then
                 begin
                 begin
-                   s:=pattern;
-                   consume(_ID);
-                   consume(_COLON);
-                   srsym:=psym(precorddef(def)^.symtable^.search(s));
-                   if srsym=nil then
-                     begin
-                        Message1(sym_e_id_not_found,s);
-                        consume_all_until(_SEMICOLON);
-                     end
-                   else
+                  p:=comp_expr(true);
+                  p:=gentypeconvnode(p,cshortstringdef);
+                  do_firstpass(p);
+                  if p.nodetype=stringconstn then
+                    begin
+                      s:=strpas(tstringconstnode(p).value_str);
+                      p.free;
+                      if string2guid(s,tmpguid) then
+                        begin
+                          curconstsegment^.concat(new(pai_const,init_32bit(tmpguid.D1)));
+                          curconstsegment^.concat(new(pai_const,init_16bit(tmpguid.D2)));
+                          curconstsegment^.concat(new(pai_const,init_16bit(tmpguid.D3)));
+                          for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
+                            curconstsegment^.concat(new(pai_const,init_8bit(tmpguid.D4[i])));
+                        end
+                      else
+                        Message(parser_e_improper_guid_syntax);
+                    end
+                  else
+                    begin
+                      p.free;
+                      Message(cg_e_illegal_expression);
+                      exit;
+                    end;
+                end
+              else
+                begin
+                   consume(_LKLAMMER);
+                   aktpos:=0;
+                   while token<>_RKLAMMER do
                      begin
                      begin
-                        { check position }
-                        if pvarsym(srsym)^.address<aktpos then
-                          Message(parser_e_invalid_record_const);
+                        s:=pattern;
+                        consume(_ID);
+                        consume(_COLON);
+                        srsym:=psym(precorddef(def)^.symtable^.search(s));
+                        if srsym=nil then
+                          begin
+                             Message1(sym_e_id_not_found,s);
+                             consume_all_until(_SEMICOLON);
+                          end
+                        else
+                          begin
+                             { check position }
+                             if pvarsym(srsym)^.address<aktpos then
+                               Message(parser_e_invalid_record_const);
 
 
-                        { if needed fill }
-                        if pvarsym(srsym)^.address>aktpos then
-                          for i:=1 to pvarsym(srsym)^.address-aktpos do
-                            curconstsegment^.concat(new(pai_const,init_8bit(0)));
+                             { if needed fill }
+                             if pvarsym(srsym)^.address>aktpos then
+                               for i:=1 to pvarsym(srsym)^.address-aktpos do
+                                 curconstsegment^.concat(new(pai_const,init_8bit(0)));
 
 
-                        { new position }
-                        aktpos:=pvarsym(srsym)^.address+pvarsym(srsym)^.vartype.def^.size;
+                             { new position }
+                             aktpos:=pvarsym(srsym)^.address+pvarsym(srsym)^.vartype.def^.size;
 
 
-                        { read the data }
-                        readtypedconst(pvarsym(srsym)^.vartype.def,nil,no_change_allowed);
+                             { read the data }
+                             readtypedconst(pvarsym(srsym)^.vartype.def,nil,no_change_allowed);
 
 
-                        if token=_SEMICOLON then
-                          consume(_SEMICOLON)
-                        else break;
-                     end;
+                             if token=_SEMICOLON then
+                               consume(_SEMICOLON)
+                             else break;
+                          end;
+                   end;
                 end;
                 end;
-              for i:=1 to def^.size-aktpos do
-                curconstsegment^.concat(new(pai_const,init_8bit(0)));
-              consume(_RKLAMMER);
            end;
            end;
          { reads a typed object }
          { reads a typed object }
          objectdef:
          objectdef:
            begin
            begin
-              if ([oo_has_vmt,oo_is_class]*pobjectdef(def)^.objectoptions)<>[] then
+              if is_class_or_interface(def) then
                 begin
                 begin
-                   { support nil assignment for classes }
-                   if pobjectdef(def)^.is_class and
-                      try_to_consume(_NIL) then
-                    begin
-                      curconstsegment^.concat(new(pai_const,init_32bit(0)));
-                    end
-                   else
+                  p:=comp_expr(true);
+                  do_firstpass(p);
+                  if p.nodetype<>niln then
                     begin
                     begin
                       Message(parser_e_type_const_not_possible);
                       Message(parser_e_type_const_not_possible);
                       consume_all_until(_RKLAMMER);
                       consume_all_until(_RKLAMMER);
+                    end
+                  else
+                    begin
+                      curconstsegment^.concat(new(pai_const,init_32bit(0)));
                     end;
                     end;
+                  p.free;
                 end
                 end
+              { for objects we allow it only if it doesn't contain a vmt }
+              else if (oo_has_vmt in pobjectdef(def)^.objectoptions) then
+                 Message(parser_e_type_const_not_possible)
               else
               else
                 begin
                 begin
                    consume(_LKLAMMER);
                    consume(_LKLAMMER);
@@ -801,7 +835,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.10  2000-10-31 22:02:51  peter
+  Revision 1.11  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.10  2000/10/31 22:02:51  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.9  2000/10/14 10:14:52  peter
   Revision 1.9  2000/10/14 10:14:52  peter

+ 6 - 5
compiler/ptype.pas

@@ -93,7 +93,7 @@ implementation
          s:=pattern;
          s:=pattern;
          pos:=akttokenpos;
          pos:=akttokenpos;
          { classes can be used also in classes }
          { classes can be used also in classes }
-         if (curobjectname=pattern) and aktobjectdef^.is_class then
+         if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
            begin
            begin
               tt.setdef(aktobjectdef);
               tt.setdef(aktobjectdef);
               consume(_ID);
               consume(_ID);
@@ -254,7 +254,7 @@ implementation
                 exit;
                 exit;
              end;
              end;
            { classes can be used also in classes }
            { classes can be used also in classes }
-           if (curobjectname=pattern) and aktobjectdef^.is_class then
+           if (curobjectname=pattern) and is_class_or_interface(aktobjectdef) then
              begin
              begin
                 tt.setdef(aktobjectdef);
                 tt.setdef(aktobjectdef);
                 consume(_ID);
                 consume(_ID);
@@ -538,9 +538,7 @@ implementation
               end;
               end;
             _CLASS,
             _CLASS,
             _CPPCLASS,
             _CPPCLASS,
-{$ifdef SUPPORTINTERFACES}
             _INTERFACE,
             _INTERFACE,
-{$endif SUPPORTINTERFACES}
             _OBJECT:
             _OBJECT:
               begin
               begin
                 tt.setdef(object_dec(name,nil));
                 tt.setdef(object_dec(name,nil));
@@ -583,7 +581,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.13  2000-10-31 22:02:51  peter
+  Revision 1.14  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.13  2000/10/31 22:02:51  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.12  2000/10/26 21:54:03  peter
   Revision 1.12  2000/10/26 21:54:03  peter

+ 8 - 1
compiler/rautils.pas

@@ -906,6 +906,10 @@ Begin
                       opr.ref.options:=ref_none;
                       opr.ref.options:=ref_none;
                     end;
                     end;
                 end;
                 end;
+              if (pvarsym(sym)^.varspez in [vs_var,vs_out]) or
+                 ((pvarsym(sym)^.varspez=vs_const) and
+                  push_addr_param(pvarsym(sym)^.vartype.def)) then
+                SetSize(target_os.size_of_pointer,false);
             end;
             end;
         end;
         end;
         case pvarsym(sym)^.vartype.def^.deftype of
         case pvarsym(sym)^.vartype.def^.deftype of
@@ -1548,7 +1552,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2000-10-31 22:30:13  peter
+  Revision 1.10  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.9  2000/10/31 22:30:13  peter
     * merged asm result patch part 2
     * merged asm result patch part 2
 
 
   Revision 1.8  2000/10/31 22:02:51  peter
   Revision 1.8  2000/10/31 22:02:51  peter

+ 5 - 2
compiler/regvars.pas

@@ -192,7 +192,7 @@ implementation
 
 
                       { possibly no 32 bit register are needed }
                       { possibly no 32 bit register are needed }
                       { call by reference/const ? }
                       { call by reference/const ? }
-                      if (regvarinfo^.regvars[i]^.varspez=vs_var) or
+                      if (regvarinfo^.regvars[i]^.varspez in [vs_var,vs_out]) or
                          ((regvarinfo^.regvars[i]^.varspez=vs_const) and
                          ((regvarinfo^.regvars[i]^.varspez=vs_const) and
                            push_addr_param(regvarinfo^.regvars[i]^.vartype.def)) then
                            push_addr_param(regvarinfo^.regvars[i]^.vartype.def)) then
                         begin
                         begin
@@ -464,7 +464,10 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2000-10-31 22:02:51  peter
+  Revision 1.12  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.11  2000/10/31 22:02:51  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.10  2000/10/14 10:14:52  peter
   Revision 1.10  2000/10/14 10:14:52  peter

+ 23 - 1
compiler/scandir.inc

@@ -36,6 +36,7 @@ type
      _DIR_I,_DIR_I386_ATT,_DIR_I386_DIRECT,_DIR_I386_INTEL,_DIR_IOCHECKS,
      _DIR_I,_DIR_I386_ATT,_DIR_I386_DIRECT,_DIR_I386_INTEL,_DIR_IOCHECKS,
        _DIR_IF,_DIR_IFDEF,_DIR_IFNDEF,_DIR_IFOPT,_DIR_INCLUDE,_DIR_INCLUDEPATH,
        _DIR_IF,_DIR_IFDEF,_DIR_IFNDEF,_DIR_IFOPT,_DIR_INCLUDE,_DIR_INCLUDEPATH,
        _DIR_INFO,_DIR_INLINE,
        _DIR_INFO,_DIR_INLINE,
+       _DIR_INTERFACES,
      _DIR_L,_DIR_LIBRARYPATH,_DIR_LINK,_DIR_LINKLIB,_DIR_LOCALSYMBOLS,
      _DIR_L,_DIR_LIBRARYPATH,_DIR_LINK,_DIR_LINKLIB,_DIR_LOCALSYMBOLS,
        _DIR_LONGSTRINGS,
        _DIR_LONGSTRINGS,
      _DIR_M,_DIR_MACRO,_DIR_MAXFPUREGISTERS,_DIR_MEMORY,_DIR_MESSAGE,_DIR_MINENUMSIZE,_DIR_MMX,_DIR_MODE,
      _DIR_M,_DIR_MACRO,_DIR_MAXFPUREGISTERS,_DIR_MEMORY,_DIR_MESSAGE,_DIR_MINENUMSIZE,_DIR_MMX,_DIR_MODE,
@@ -90,6 +91,7 @@ const
      'INCLUDEPATH',
      'INCLUDEPATH',
      'INFO',
      'INFO',
      'INLINE',
      'INLINE',
+     'INTERFACES',
      'L',
      'L',
      'LIBRARYPATH',
      'LIBRARYPATH',
      'LINK',
      'LINK',
@@ -575,6 +577,22 @@ const
          end;
          end;
       end;
       end;
 
 
+    procedure dir_interfacesswitch(t:tdirectivetoken);
+      var
+        hs : string;
+      begin
+        {corba/com/default}
+        current_scanner^.skipspace;
+        hs:=current_scanner^.readid;
+        if (hs='CORBA') then
+          aktinterfacetype:=it_interfacecorba
+        else if (hs='COM') then
+          aktinterfacetype:=it_interfacecom
+        else if (hs='DEFAULT') then
+          aktinterfacetype:=initinterfacetype
+        else
+          Message(scan_e_invalid_interface_type);
+      end;
 
 
     procedure dir_localswitch(t:tdirectivetoken);
     procedure dir_localswitch(t:tdirectivetoken);
       var
       var
@@ -1302,6 +1320,7 @@ const
          {_DIR_INCLUDEPATH} dir_includepath,
          {_DIR_INCLUDEPATH} dir_includepath,
          {_DIR_INFO} dir_message,
          {_DIR_INFO} dir_message,
          {_DIR_INLINE} dir_moduleswitch,
          {_DIR_INLINE} dir_moduleswitch,
+         {_DIR_INTERFACES} dir_interfacesswitch,
          {_DIR_L} dir_linkobject,
          {_DIR_L} dir_linkobject,
          {_DIR_LIBRARYPATH} dir_librarypath,
          {_DIR_LIBRARYPATH} dir_librarypath,
          {_DIR_LINK} dir_linkobject,
          {_DIR_LINK} dir_linkobject,
@@ -1436,7 +1455,10 @@ const
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.10  2000-10-31 22:02:51  peter
+  Revision 1.11  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.10  2000/10/31 22:02:51  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.9  2000/09/26 10:50:41  jonas
   Revision 1.9  2000/09/26 10:50:41  jonas

+ 15 - 6
compiler/symconst.pas

@@ -54,6 +54,7 @@ const
   tkInt64    = 19;
   tkInt64    = 19;
   tkQWord    = 20;
   tkQWord    = 20;
   tkDynArray = 21;
   tkDynArray = 21;
+  tkInterfaceCorba = 22;
 
 
   otSByte    = 0;
   otSByte    = 0;
   otUByte    = 1;
   otUByte    = 1;
@@ -196,9 +197,17 @@ type
   );
   );
   tprocoptions=set of tprocoption;
   tprocoptions=set of tprocoption;
 
 
+  { options for objects and classes }
+  tobjectdeftype = (
+    odt_class,
+    odt_object,
+    odt_interfacecom,
+    odt_interfacecorba,
+    odt_cppclass
+  );
+
   { options for objects and classes }
   { options for objects and classes }
   tobjectoption=(oo_none,
   tobjectoption=(oo_none,
-    oo_is_class,
     oo_is_forward,         { the class is only a forward declared yet }
     oo_is_forward,         { the class is only a forward declared yet }
     oo_has_virtual,        { the object/class has virtual methods }
     oo_has_virtual,        { the object/class has virtual methods }
     oo_has_private,
     oo_has_private,
@@ -209,10 +218,7 @@ type
     oo_has_msgstr,
     oo_has_msgstr,
     oo_has_msgint,
     oo_has_msgint,
     oo_has_abstract,       { the object/class has an abstract method => no instances can be created }
     oo_has_abstract,       { the object/class has an abstract method => no instances can be created }
-    oo_can_have_published, { the class has rtti, i.e. you can publish properties }
-    oo_is_cppclass,        { the object/class uses an C++ compatible }
-                           { class layout }
-    oo_is_interface        { delphi styled interface }
+    oo_can_have_published { the class has rtti, i.e. you can publish properties }
   );
   );
 
 
   tobjectoptions=set of tobjectoption;
   tobjectoptions=set of tobjectoption;
@@ -322,7 +328,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2000-10-31 22:02:51  peter
+  Revision 1.12  2000-11-04 14:25:21  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.11  2000/10/31 22:02:51  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
   Revision 1.9  2000/10/15 07:47:52  peter
   Revision 1.9  2000/10/15 07:47:52  peter

+ 4805 - 0
compiler/symdef.inc

@@ -0,0 +1,4805 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
+
+    Symbol table implementation for the definitions
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+
+{****************************************************************************
+                     TDEF (base class for definitions)
+****************************************************************************}
+
+    function tparalinkedlist.count:longint;
+      begin
+        { You must use tabstractprocdef.minparacount and .maxparacount instead }
+        internalerror(432432978);
+        count:=0;
+      end;
+
+
+{****************************************************************************
+                     TDEF (base class for definitions)
+****************************************************************************}
+
+
+    constructor tdef.init;
+      begin
+         inherited init;
+         deftype:=abstractdef;
+         owner := nil;
+         typesym := nil;
+         savesize := 0;
+         if registerdef then
+           symtablestack^.registerdef(@self);
+         has_rtti:=false;
+         has_inittable:=false;
+{$ifdef GDB}
+         is_def_stab_written := not_written;
+         globalnb := 0;
+{$endif GDB}
+         if assigned(lastglobaldef) then
+           begin
+              lastglobaldef^.nextglobal := @self;
+              previousglobal:=lastglobaldef;
+           end
+         else
+           begin
+              firstglobaldef := @self;
+              previousglobal := nil;
+           end;
+         lastglobaldef := @self;
+         nextglobal := nil;
+      end;
+
+{$ifdef MEMDEBUG}
+   var
+       manglenamesize : longint;
+{$endif}
+
+    constructor tdef.load;
+      begin
+         inherited init;
+         deftype:=abstractdef;
+         owner := nil;
+         has_rtti:=false;
+         has_inittable:=false;
+{$ifdef GDB}
+         is_def_stab_written := not_written;
+         globalnb := 0;
+{$endif GDB}
+         if assigned(lastglobaldef) then
+           begin
+              lastglobaldef^.nextglobal := @self;
+              previousglobal:=lastglobaldef;
+           end
+         else
+           begin
+              firstglobaldef := @self;
+              previousglobal:=nil;
+           end;
+         lastglobaldef := @self;
+         nextglobal := nil;
+      { load }
+         indexnr:=readword;
+         typesym:=ptypesym(readsymref);
+      end;
+
+
+    destructor tdef.done;
+      begin
+         { first element  ? }
+         if not(assigned(previousglobal)) then
+           begin
+              firstglobaldef := nextglobal;
+              if assigned(firstglobaldef) then
+                firstglobaldef^.previousglobal:=nil;
+           end
+         else
+           begin
+              { remove reference in the element before }
+              previousglobal^.nextglobal:=nextglobal;
+           end;
+         { last element ? }
+         if not(assigned(nextglobal)) then
+           begin
+              lastglobaldef := previousglobal;
+              if assigned(lastglobaldef) then
+                lastglobaldef^.nextglobal:=nil;
+           end
+         else
+           nextglobal^.previousglobal:=previousglobal;
+         previousglobal:=nil;
+         nextglobal:=nil;
+{$ifdef SYNONYM}
+         while assigned(typesym) do
+           begin
+              typesym^.restype.setdef(nil);
+              typesym:=typesym^.synonym;
+           end;
+{$endif}
+      end;
+
+    { used for enumdef because the symbols are
+      inserted in the owner symtable }
+    procedure tdef.correct_owner_symtable;
+      var
+         st : psymtable;
+      begin
+         if assigned(owner) and
+            (owner^.symtabletype in [recordsymtable,objectsymtable]) then
+           begin
+              owner^.defindex^.deleteindex(@self);
+              st:=owner;
+              while (st^.symtabletype in [recordsymtable,objectsymtable]) do
+                st:=st^.next;
+              st^.registerdef(@self);
+           end;
+      end;
+
+
+    function tdef.typename:string;
+      begin
+        if assigned(typesym) and not(deftype=procvardef) and
+          assigned(typesym^._realname) and
+          (typesym^._realname^[1]<>'$') then
+         typename:=typesym^._realname^
+        else
+         typename:=gettypename;
+      end;
+
+    function tdef.gettypename : string;
+
+      begin
+         gettypename:='<unknown type>'
+      end;
+
+    function tdef.is_in_current : boolean;
+      var
+        p : psymtable;
+      begin
+         p:=owner;
+         is_in_current:=false;
+         while assigned(p) do
+           begin
+              if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
+                 or (p^.symtabletype in [globalsymtable,staticsymtable]) then
+                begin
+                   is_in_current:=true;
+                   exit;
+                end
+              else if p^.symtabletype in [localsymtable,parasymtable,objectsymtable] then
+                begin
+                  if assigned(p^.defowner) then
+                    p:=pobjectdef(p^.defowner)^.owner
+                  else
+                    exit;
+                end
+              else
+                exit;
+           end;
+
+      end;
+
+    procedure tdef.write;
+      begin
+        writeword(indexnr);
+        writesymref(typesym);
+{$ifdef GDB}
+        if globalnb = 0 then
+          begin
+            if assigned(owner) then
+              globalnb := owner^.getnewtypecount
+            else
+              begin
+                globalnb := PGlobalTypeCount^;
+                Inc(PGlobalTypeCount^);
+              end;
+           end;
+{$endif GDB}
+      end;
+
+
+    function tdef.size : longint;
+      begin
+         size:=savesize;
+      end;
+
+
+    function tdef.alignment : longint;
+      begin
+         { normal alignment by default }
+         alignment:=0;
+      end;
+
+
+{$ifdef GDB}
+   procedure tdef.set_globalnb;
+     begin
+         globalnb :=PGlobalTypeCount^;
+         inc(PglobalTypeCount^);
+     end;
+
+    function tdef.stabstring : pchar;
+      begin
+      stabstring := strpnew('t'+numberstring+';');
+      end;
+
+
+    function tdef.numberstring : string;
+      var table : psymtable;
+      begin
+      {formal def have no type !}
+      if deftype = formaldef then
+        begin
+        numberstring := voiddef^.numberstring;
+        exit;
+        end;
+      if (not assigned(typesym)) or (not typesym^.isusedinstab) then
+        begin
+           {set even if debuglist is not defined}
+           if assigned(typesym) then
+             typesym^.isusedinstab := true;
+           if assigned(debuglist) and (is_def_stab_written = not_written) then
+             concatstabto(debuglist);
+        end;
+      if not (cs_gdb_dbx in aktglobalswitches) then
+        begin
+           if globalnb = 0 then
+             set_globalnb;
+           numberstring := tostr(globalnb);
+        end
+      else
+        begin
+           if globalnb = 0 then
+             begin
+                if assigned(owner) then
+                  globalnb := owner^.getnewtypecount
+                else
+                  begin
+                     globalnb := PGlobalTypeCount^;
+                     Inc(PGlobalTypeCount^);
+                  end;
+             end;
+           if assigned(typesym) then
+             begin
+                table := typesym^.owner;
+                if table^.unitid > 0 then
+                  numberstring := '('+tostr(table^.unitid)+','+tostr(typesym^.restype.def^.globalnb)+')'
+                else
+                  numberstring := tostr(globalnb);
+                exit;
+             end;
+           numberstring := tostr(globalnb);
+        end;
+      end;
+
+
+    function tdef.allstabstring : pchar;
+    var stabchar : string[2];
+        ss,st : pchar;
+        sname : string;
+        sym_line_no : longint;
+      begin
+      ss := stabstring;
+      getmem(st,strlen(ss)+512);
+      stabchar := 't';
+      if deftype in tagtypes then
+        stabchar := 'Tt';
+      if assigned(typesym) then
+        begin
+           sname := typesym^.name;
+           sym_line_no:=typesym^.fileinfo.line;
+        end
+      else
+        begin
+           sname := ' ';
+           sym_line_no:=0;
+        end;
+      strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
+      strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
+      allstabstring := strnew(st);
+      freemem(st,strlen(ss)+512);
+      strdispose(ss);
+      end;
+
+
+    procedure tdef.concatstabto(asmlist : paasmoutput);
+     var stab_str : pchar;
+    begin
+    if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
+      and (is_def_stab_written = not_written) then
+      begin
+      If cs_gdb_dbx in aktglobalswitches then
+        begin
+           { otherwise you get two of each def }
+           If assigned(typesym) then
+             begin
+                if typesym^.typ=symconst.typesym then
+                  typesym^.isusedinstab:=true;
+                if (typesym^.owner = nil) or
+                  ((typesym^.owner^.symtabletype = unitsymtable) and
+                 punitsymtable(typesym^.owner)^.dbx_count_ok)  then
+                begin
+                   {with DBX we get the definition from the other objects }
+                   is_def_stab_written := written;
+                   exit;
+                end;
+             end;
+        end;
+      { to avoid infinite loops }
+      is_def_stab_written := being_written;
+      stab_str := allstabstring;
+      asmlist^.concat(new(pai_stabs,init(stab_str)));
+      is_def_stab_written := written;
+      end;
+    end;
+{$endif GDB}
+
+
+    procedure tdef.deref;
+      begin
+        resolvesym(psym(typesym));
+      end;
+
+
+    { rtti generation }
+    procedure tdef.generate_rtti;
+      begin
+         if not has_rtti then
+          begin
+            has_rtti:=true;
+            getdatalabel(rtti_label);
+            write_child_rtti_data;
+            rttilist^.concat(new(pai_symbol,init(rtti_label,0)));
+            write_rtti_data;
+            rttilist^.concat(new(pai_symbol_end,init(rtti_label)));
+          end;
+      end;
+
+
+    function tdef.get_rtti_label : string;
+      begin
+         generate_rtti;
+         get_rtti_label:=rtti_label^.name;
+      end;
+
+
+    { init table handling }
+    function tdef.needs_inittable : boolean;
+      begin
+         needs_inittable:=false;
+      end;
+
+
+    procedure tdef.generate_inittable;
+      begin
+         has_inittable:=true;
+         getdatalabel(inittable_label);
+         write_child_init_data;
+         rttilist^.concat(new(pai_label,init(inittable_label)));
+         write_init_data;
+      end;
+
+
+    procedure tdef.write_init_data;
+      begin
+         write_rtti_data;
+      end;
+
+
+    procedure tdef.write_child_init_data;
+      begin
+         write_child_rtti_data;
+      end;
+
+
+    function tdef.get_inittable_label : pasmlabel;
+      begin
+         if not(has_inittable) then
+           generate_inittable;
+         get_inittable_label:=inittable_label;
+      end;
+
+
+    procedure tdef.write_rtti_name;
+      var
+         str : string;
+      begin
+         { name }
+         if assigned(typesym) then
+           begin
+              str:=typesym^.realname;
+              rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
+           end
+         else
+           rttilist^.concat(new(pai_string,init(#0)))
+      end;
+
+
+    { returns true, if the definition can be published }
+    function tdef.is_publishable : boolean;
+      begin
+         is_publishable:=false;
+      end;
+
+
+    procedure tdef.write_rtti_data;
+      begin
+      end;
+
+
+    procedure tdef.write_child_rtti_data;
+      begin
+      end;
+
+
+   function tdef.is_intregable : boolean;
+
+     begin
+        is_intregable:=false;
+        case deftype of
+          pointerdef,
+          enumdef,
+          procvardef :
+            is_intregable:=true;
+          orddef :
+            case porddef(@self)^.typ of
+              bool8bit,bool16bit,bool32bit,
+              u8bit,u16bit,u32bit,
+              s8bit,s16bit,s32bit:
+                is_intregable:=true;
+            end;
+          setdef:
+            is_intregable:=is_smallset(@self);
+        end;
+     end;
+
+   function tdef.is_fpuregable : boolean;
+
+     begin
+        is_fpuregable:=(deftype=floatdef) and not(pfloatdef(@self)^.typ in [f32bit,f16bit]);
+     end;
+
+{****************************************************************************
+                               TSTRINGDEF
+****************************************************************************}
+
+    constructor tstringdef.shortinit(l : byte);
+      begin
+         tdef.init;
+         string_typ:=st_shortstring;
+         deftype:=stringdef;
+         len:=l;
+         savesize:=len+1;
+      end;
+
+
+    constructor tstringdef.shortload;
+      begin
+         tdef.load;
+         string_typ:=st_shortstring;
+         deftype:=stringdef;
+         len:=readbyte;
+         savesize:=len+1;
+      end;
+
+
+    constructor tstringdef.longinit(l : longint);
+      begin
+         tdef.init;
+         string_typ:=st_longstring;
+         deftype:=stringdef;
+         len:=l;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tstringdef.longload;
+      begin
+         tdef.load;
+         deftype:=stringdef;
+         string_typ:=st_longstring;
+         len:=readlong;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tstringdef.ansiinit(l : longint);
+      begin
+         tdef.init;
+         string_typ:=st_ansistring;
+         deftype:=stringdef;
+         len:=l;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tstringdef.ansiload;
+      begin
+         tdef.load;
+         deftype:=stringdef;
+         string_typ:=st_ansistring;
+         len:=readlong;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tstringdef.wideinit(l : longint);
+      begin
+         tdef.init;
+         string_typ:=st_widestring;
+         deftype:=stringdef;
+         len:=l;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tstringdef.wideload;
+      begin
+         tdef.load;
+         deftype:=stringdef;
+         string_typ:=st_widestring;
+         len:=readlong;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    function tstringdef.stringtypname:string;
+      const
+        typname:array[tstringtype] of string[8]=('',
+          'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
+        );
+      begin
+        stringtypname:=typname[string_typ];
+      end;
+
+
+    function tstringdef.size : longint;
+      begin
+        size:=savesize;
+      end;
+
+
+    procedure tstringdef.write;
+      begin
+         tdef.write;
+         if string_typ=st_shortstring then
+           writebyte(len)
+         else
+           writelong(len);
+         case string_typ of
+           st_shortstring : current_ppu^.writeentry(ibshortstringdef);
+            st_longstring : current_ppu^.writeentry(iblongstringdef);
+            st_ansistring : current_ppu^.writeentry(ibansistringdef);
+            st_widestring : current_ppu^.writeentry(ibwidestringdef);
+         end;
+      end;
+
+
+{$ifdef GDB}
+    function tstringdef.stabstring : pchar;
+      var
+        bytest,charst,longst : string;
+      begin
+        case string_typ of
+           st_shortstring:
+             begin
+               charst := typeglobalnumber('char');
+               { this is what I found in stabs.texinfo but
+                 gdb 4.12 for go32 doesn't understand that !! }
+             {$IfDef GDBknowsstrings}
+               stabstring := strpnew('n'+charst+';'+tostr(len));
+             {$else}
+               bytest := typeglobalnumber('byte');
+               stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
+                  +',0,8;st:ar'+bytest
+                  +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
+             {$EndIf}
+             end;
+           st_longstring:
+             begin
+               charst := typeglobalnumber('char');
+               { this is what I found in stabs.texinfo but
+                 gdb 4.12 for go32 doesn't understand that !! }
+             {$IfDef GDBknowsstrings}
+               stabstring := strpnew('n'+charst+';'+tostr(len));
+             {$else}
+               bytest := typeglobalnumber('byte');
+               longst := typeglobalnumber('longint');
+               stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
+                  +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
+                  +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
+             {$EndIf}
+             end;
+           st_ansistring:
+             begin
+               { an ansi string looks like a pchar easy !! }
+               stabstring:=strpnew('*'+typeglobalnumber('char'));
+             end;
+           st_widestring:
+             begin
+               { an ansi string looks like a pchar easy !! }
+               stabstring:=strpnew('*'+typeglobalnumber('char'));
+             end;
+      end;
+    end;
+
+
+    procedure tstringdef.concatstabto(asmlist : paasmoutput);
+      begin
+        inherited concatstabto(asmlist);
+      end;
+{$endif GDB}
+
+
+    function tstringdef.needs_inittable : boolean;
+      begin
+         needs_inittable:=string_typ in [st_ansistring,st_widestring];
+      end;
+
+    function tstringdef.gettypename : string;
+
+      const
+         names : array[tstringtype] of string[20] = ('',
+           'ShortString','LongString','AnsiString','WideString');
+
+      begin
+         gettypename:=names[string_typ];
+      end;
+
+    procedure tstringdef.write_rtti_data;
+      begin
+         case string_typ of
+            st_ansistring:
+              begin
+                 rttilist^.concat(new(pai_const,init_8bit(tkAString)));
+                 write_rtti_name;
+              end;
+            st_widestring:
+              begin
+                 rttilist^.concat(new(pai_const,init_8bit(tkWString)));
+                 write_rtti_name;
+              end;
+            st_longstring:
+              begin
+                 rttilist^.concat(new(pai_const,init_8bit(tkLString)));
+                 write_rtti_name;
+              end;
+            st_shortstring:
+              begin
+                 rttilist^.concat(new(pai_const,init_8bit(tkSString)));
+                 write_rtti_name;
+                 rttilist^.concat(new(pai_const,init_8bit(len)));
+              end;
+         end;
+      end;
+
+
+    function tstringdef.is_publishable : boolean;
+      begin
+         is_publishable:=true;
+      end;
+
+
+{****************************************************************************
+                                 TENUMDEF
+****************************************************************************}
+
+    constructor tenumdef.init;
+      begin
+         tdef.init;
+         deftype:=enumdef;
+         minval:=0;
+         maxval:=0;
+         calcsavesize;
+         has_jumps:=false;
+         basedef:=nil;
+         rangenr:=0;
+         firstenum:=nil;
+         correct_owner_symtable;
+      end;
+
+    constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
+      begin
+         tdef.init;
+         deftype:=enumdef;
+         minval:=_min;
+         maxval:=_max;
+         basedef:=_basedef;
+         calcsavesize;
+         has_jumps:=false;
+         rangenr:=0;
+         firstenum:=basedef^.firstenum;
+         while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
+          firstenum:=firstenum^.nextenum;
+         correct_owner_symtable;
+      end;
+
+
+    constructor tenumdef.load;
+      begin
+         tdef.load;
+         deftype:=enumdef;
+         basedef:=penumdef(readdefref);
+         minval:=readlong;
+         maxval:=readlong;
+         savesize:=readlong;
+         has_jumps:=false;
+         firstenum:=Nil;
+      end;
+
+
+    procedure tenumdef.calcsavesize;
+      begin
+        if (aktpackenum=4) or (min<0) or (max>65535) then
+         savesize:=4
+        else
+         if (aktpackenum=2) or (min<0) or (max>255) then
+          savesize:=2
+        else
+         savesize:=1;
+      end;
+
+
+    procedure tenumdef.setmax(_max:longint);
+      begin
+        maxval:=_max;
+        calcsavesize;
+      end;
+
+
+    procedure tenumdef.setmin(_min:longint);
+      begin
+        minval:=_min;
+        calcsavesize;
+      end;
+
+
+    function tenumdef.min:longint;
+      begin
+        min:=minval;
+      end;
+
+
+    function tenumdef.max:longint;
+      begin
+        max:=maxval;
+      end;
+
+
+    procedure tenumdef.deref;
+      begin
+        inherited deref;
+        resolvedef(pdef(basedef));
+      end;
+
+
+    destructor tenumdef.done;
+      begin
+        inherited done;
+      end;
+
+
+    procedure tenumdef.write;
+      begin
+         tdef.write;
+         writedefref(basedef);
+         writelong(min);
+         writelong(max);
+         writelong(savesize);
+         current_ppu^.writeentry(ibenumdef);
+      end;
+
+
+    function tenumdef.getrangecheckstring : string;
+      begin
+         if (cs_create_smart in aktmoduleswitches) then
+           getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
+         else
+           getrangecheckstring:='R_'+tostr(rangenr);
+      end;
+
+
+    procedure tenumdef.genrangecheck;
+      begin
+         if rangenr=0 then
+           begin
+              { generate two constant for bounds }
+              getlabelnr(rangenr);
+              if (cs_create_smart in aktmoduleswitches) then
+                datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
+              else
+                datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
+              datasegment^.concat(new(pai_const,init_32bit(min)));
+              datasegment^.concat(new(pai_const,init_32bit(max)));
+           end;
+      end;
+
+
+{$ifdef GDB}
+    function tenumdef.stabstring : pchar;
+      var st,st2 : pchar;
+          p : penumsym;
+          s : string;
+          memsize : word;
+      begin
+        memsize := memsizeinc;
+        getmem(st,memsize);
+        strpcopy(st,'e');
+        p := firstenum;
+        while assigned(p) do
+          begin
+            s :=p^.name+':'+tostr(p^.value)+',';
+            { place for the ending ';' also }
+            if (strlen(st)+length(s)+1<memsize) then
+              strpcopy(strend(st),s)
+            else
+              begin
+                getmem(st2,memsize+memsizeinc);
+                strcopy(st2,st);
+                freemem(st,memsize);
+                st := st2;
+                memsize := memsize+memsizeinc;
+                strpcopy(strend(st),s);
+              end;
+            p := p^.nextenum;
+          end;
+        strpcopy(strend(st),';');
+        stabstring := strnew(st);
+        freemem(st,memsize);
+      end;
+{$endif GDB}
+
+
+    procedure tenumdef.write_child_rtti_data;
+      begin
+         if assigned(basedef) then
+           basedef^.get_rtti_label;
+      end;
+
+
+    procedure tenumdef.write_rtti_data;
+
+      var
+         hp : penumsym;
+
+      begin
+         rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
+         write_rtti_name;
+         case savesize of
+            1:
+              rttilist^.concat(new(pai_const,init_8bit(otUByte)));
+            2:
+              rttilist^.concat(new(pai_const,init_8bit(otUWord)));
+            4:
+              rttilist^.concat(new(pai_const,init_8bit(otULong)));
+         end;
+         rttilist^.concat(new(pai_const,init_32bit(min)));
+         rttilist^.concat(new(pai_const,init_32bit(max)));
+         if assigned(basedef) then
+           rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
+         else
+           rttilist^.concat(new(pai_const,init_32bit(0)));
+         hp:=firstenum;
+         while assigned(hp) do
+           begin
+              rttilist^.concat(new(pai_const,init_8bit(length(hp^.name))));
+              rttilist^.concat(new(pai_string,init(lower(hp^.name))));
+              hp:=hp^.nextenum;
+           end;
+         rttilist^.concat(new(pai_const,init_8bit(0)));
+      end;
+
+
+    function tenumdef.is_publishable : boolean;
+      begin
+         is_publishable:=true;
+      end;
+
+    function tenumdef.gettypename : string;
+
+      begin
+         gettypename:='<enumeration type>';
+      end;
+
+{****************************************************************************
+                                 TORDDEF
+****************************************************************************}
+
+    constructor torddef.init(t : tbasetype;v,b : longint);
+      begin
+         inherited init;
+         deftype:=orddef;
+         low:=v;
+         high:=b;
+         typ:=t;
+         rangenr:=0;
+         setsize;
+      end;
+
+
+    constructor torddef.load;
+      begin
+         inherited load;
+         deftype:=orddef;
+         typ:=tbasetype(readbyte);
+         low:=readlong;
+         high:=readlong;
+         rangenr:=0;
+         setsize;
+      end;
+
+
+    procedure torddef.setsize;
+      begin
+         if typ=uauto then
+           begin
+              { generate a unsigned range if high<0 and low>=0 }
+              if (low>=0) and (high<0) then
+                begin
+                   savesize:=4;
+                   typ:=u32bit;
+                end
+              else if (low>=0) and (high<=255) then
+                begin
+                   savesize:=1;
+                   typ:=u8bit;
+                end
+              else if (low>=-128) and (high<=127) then
+                begin
+                   savesize:=1;
+                   typ:=s8bit;
+                end
+              else if (low>=0) and (high<=65536) then
+                begin
+                   savesize:=2;
+                   typ:=u16bit;
+                end
+              else if (low>=-32768) and (high<=32767) then
+                begin
+                   savesize:=2;
+                   typ:=s16bit;
+                end
+              else
+                begin
+                   savesize:=4;
+                   typ:=s32bit;
+                end;
+           end
+         else
+           begin
+             case typ of
+                u8bit,s8bit,
+                uchar,bool8bit:
+                  savesize:=1;
+
+                u16bit,s16bit,
+                bool16bit,uwidechar:
+                  savesize:=2;
+
+                s32bit,u32bit,
+                bool32bit:
+                  savesize:=4;
+
+                u64bit,s64bit:
+                  savesize:=8;
+             else
+               savesize:=0;
+             end;
+           end;
+       { there are no entrys for range checking }
+         rangenr:=0;
+      end;
+
+    function torddef.getrangecheckstring : string;
+
+      begin
+         if (cs_create_smart in aktmoduleswitches) then
+           getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
+         else
+           getrangecheckstring:='R_'+tostr(rangenr);
+      end;
+
+    procedure torddef.genrangecheck;
+      var
+        rangechecksize : longint;
+      begin
+         if rangenr=0 then
+           begin
+              if low<=high then
+               rangechecksize:=8
+              else
+               rangechecksize:=16;
+              { generate two constant for bounds }
+              getlabelnr(rangenr);
+              if (cs_create_smart in aktmoduleswitches) then
+                datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,rangechecksize)))
+              else
+                datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,rangechecksize)));
+              if low<=high then
+                begin
+                   datasegment^.concat(new(pai_const,init_32bit(low)));
+                   datasegment^.concat(new(pai_const,init_32bit(high)));
+                end
+              { for u32bit we need two bounds }
+              else
+                begin
+                   datasegment^.concat(new(pai_const,init_32bit(low)));
+                   datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
+                   datasegment^.concat(new(pai_const,init_32bit($80000000)));
+                   datasegment^.concat(new(pai_const,init_32bit(high)));
+                end;
+           end;
+      end;
+
+
+    procedure torddef.write;
+      begin
+         tdef.write;
+         writebyte(byte(typ));
+         writelong(low);
+         writelong(high);
+         current_ppu^.writeentry(iborddef);
+      end;
+
+
+{$ifdef GDB}
+    function torddef.stabstring : pchar;
+      begin
+        case typ of
+            uvoid : stabstring := strpnew(numberstring+';');
+         {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
+{$ifdef Use_integer_types_for_boolean}
+         bool8bit,
+        bool16bit,
+        bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
+{$else : not Use_integer_types_for_boolean}
+         bool8bit : stabstring := strpnew('-21;');
+        bool16bit : stabstring := strpnew('-22;');
+        bool32bit : stabstring := strpnew('-23;');
+        u64bit    : stabstring := strpnew('-32;');
+        s64bit    : stabstring := strpnew('-31;');
+{$endif not Use_integer_types_for_boolean}
+         { u32bit : stabstring := strpnew('r'+
+              s32bitdef^.numberstring+';0;-1;'); }
+        else
+          stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
+        end;
+      end;
+{$endif GDB}
+
+
+    procedure torddef.write_rtti_data;
+
+        procedure dointeger;
+        const
+          trans : array[uchar..bool8bit] of byte =
+            (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
+        begin
+          write_rtti_name;
+          rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
+          rttilist^.concat(new(pai_const,init_32bit(low)));
+          rttilist^.concat(new(pai_const,init_32bit(high)));
+        end;
+
+      begin
+        case typ of
+          s64bit :
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkInt64)));
+              write_rtti_name;
+              { low }
+              rttilist^.concat(new(pai_const,init_32bit($0)));
+              rttilist^.concat(new(pai_const,init_32bit($8000)));
+              { high }
+              rttilist^.concat(new(pai_const,init_32bit($ffff)));
+              rttilist^.concat(new(pai_const,init_32bit($7fff)));
+            end;
+          u64bit :
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkQWord)));
+              write_rtti_name;
+              { low }
+              rttilist^.concat(new(pai_const,init_32bit($0)));
+              rttilist^.concat(new(pai_const,init_32bit($0)));
+              { high }
+              rttilist^.concat(new(pai_const,init_32bit($0)));
+              rttilist^.concat(new(pai_const,init_32bit($8000)));
+            end;
+          bool8bit:
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkBool)));
+              dointeger;
+            end;
+          uchar:
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkWChar)));
+              dointeger;
+            end;
+          uwidechar:
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkChar)));
+              dointeger;
+            end;
+          else
+            begin
+              rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
+              dointeger;
+            end;
+        end;
+      end;
+
+
+    function torddef.is_publishable : boolean;
+      begin
+         is_publishable:=typ in [uchar..bool8bit];
+      end;
+
+    function torddef.gettypename : string;
+
+      const
+        names : array[tbasetype] of string[20] = ('<unknown type>',
+          'untyped','Char','Byte','Word','DWord','ShortInt',
+          'SmallInt','LongInt','Boolean','WordBool',
+          'LongBool','QWord','Int64','WideChar');
+
+      begin
+         gettypename:=names[typ];
+      end;
+
+{****************************************************************************
+                                TFLOATDEF
+****************************************************************************}
+
+    constructor tfloatdef.init(t : tfloattype);
+      begin
+         inherited init;
+         deftype:=floatdef;
+         typ:=t;
+         setsize;
+      end;
+
+
+    constructor tfloatdef.load;
+      begin
+         inherited load;
+         deftype:=floatdef;
+         typ:=tfloattype(readbyte);
+         setsize;
+      end;
+
+
+    procedure tfloatdef.setsize;
+      begin
+         case typ of
+            f16bit : savesize:=2;
+            f32bit,
+           s32real : savesize:=4;
+           s64real : savesize:=8;
+           s80real : savesize:=extended_size;
+           s64comp : savesize:=8;
+         else
+           savesize:=0;
+         end;
+      end;
+
+
+    procedure tfloatdef.write;
+      begin
+         inherited write;
+         writebyte(byte(typ));
+         current_ppu^.writeentry(ibfloatdef);
+      end;
+
+
+{$ifdef GDB}
+    function tfloatdef.stabstring : pchar;
+      begin
+         case typ of
+            s32real,
+            s64real : stabstring := strpnew('r'+
+               s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
+            { for fixed real use longint instead to be able to }
+            { debug something at least                         }
+            f32bit:
+              stabstring := s32bitdef^.stabstring;
+            f16bit:
+              stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
+                tostr($ffff)+';');
+            { found this solution in stabsread.c from GDB v4.16 }
+            s64comp : stabstring := strpnew('r'+
+               s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
+{$ifdef i386}
+            { under dos at least you must give a size of twelve instead of 10 !! }
+            { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
+            s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
+{$endif i386}
+            else
+              internalerror(10005);
+         end;
+      end;
+{$endif GDB}
+
+
+    procedure tfloatdef.write_rtti_data;
+      const
+         {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
+         translate : array[tfloattype] of byte =
+           (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
+      begin
+         rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
+         write_rtti_name;
+         rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
+      end;
+
+
+    function tfloatdef.is_publishable : boolean;
+      begin
+         is_publishable:=true;
+      end;
+
+    function tfloatdef.gettypename : string;
+
+      const
+        names : array[tfloattype] of string[20] = (
+          'Single','Double','Extended','Comp','Fixed','Fixed16');
+
+      begin
+         gettypename:=names[typ];
+      end;
+
+{****************************************************************************
+                                TFILEDEF
+****************************************************************************}
+
+    constructor tfiledef.inittext;
+      begin
+         inherited init;
+         deftype:=filedef;
+         filetyp:=ft_text;
+         typedfiletype.reset;
+         setsize;
+      end;
+
+
+    constructor tfiledef.inituntyped;
+      begin
+         inherited init;
+         deftype:=filedef;
+         filetyp:=ft_untyped;
+         typedfiletype.reset;
+         setsize;
+      end;
+
+
+    constructor tfiledef.inittyped(const tt : ttype);
+      begin
+         inherited init;
+         deftype:=filedef;
+         filetyp:=ft_typed;
+         typedfiletype:=tt;
+         setsize;
+      end;
+
+
+    constructor tfiledef.inittypeddef(p : pdef);
+      begin
+         inherited init;
+         deftype:=filedef;
+         filetyp:=ft_typed;
+         typedfiletype.setdef(p);
+         setsize;
+      end;
+
+
+    constructor tfiledef.load;
+      begin
+         inherited load;
+         deftype:=filedef;
+         filetyp:=tfiletyp(readbyte);
+         if filetyp=ft_typed then
+           typedfiletype.load
+         else
+           typedfiletype.reset;
+         setsize;
+      end;
+
+
+    procedure tfiledef.deref;
+      begin
+        inherited deref;
+        if filetyp=ft_typed then
+          typedfiletype.resolve;
+      end;
+
+
+    procedure tfiledef.setsize;
+      begin
+        case filetyp of
+          ft_text :
+            savesize:=572;
+          ft_typed,
+          ft_untyped :
+            savesize:=316;
+        end;
+      end;
+
+
+    procedure tfiledef.write;
+      begin
+         inherited write;
+         writebyte(byte(filetyp));
+         if filetyp=ft_typed then
+           typedfiletype.write;
+         current_ppu^.writeentry(ibfiledef);
+      end;
+
+
+{$ifdef GDB}
+    function tfiledef.stabstring : pchar;
+      begin
+   {$IfDef GDBknowsfiles}
+      case filetyp of
+        ft_typed :
+          stabstring := strpnew('d'+typedfiletype.def^.numberstring{+';'});
+        ft_untyped :
+          stabstring := strpnew('d'+voiddef^.numberstring{+';'});
+        ft_text :
+          stabstring := strpnew('d'+cchardef^.numberstring{+';'});
+      end;
+   {$Else}
+      {based on
+        FileRec = Packed Record
+          Handle,
+          Mode,
+          RecSize   : longint;
+          _private  : array[1..32] of byte;
+          UserData  : array[1..16] of byte;
+          name      : array[0..255] of char;
+        End; }
+      { the buffer part is still missing !! (PM) }
+      { but the string could become too long !! }
+      stabstring := strpnew('s'+tostr(savesize)+
+                     'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
+                     'MODE:'+typeglobalnumber('longint')+',32,32;'+
+                     'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
+                     '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
+                        +',96,256;'+
+                     'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
+                        +',352,128;'+
+                     'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
+                        +',480,2048;;');
+   {$EndIf}
+      end;
+
+
+    procedure tfiledef.concatstabto(asmlist : paasmoutput);
+      begin
+      { most file defs are unnamed !!! }
+      if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
+         (is_def_stab_written  = not_written) then
+        begin
+        if assigned(typedfiletype.def) then forcestabto(asmlist,typedfiletype.def);
+        inherited concatstabto(asmlist);
+        end;
+      end;
+{$endif GDB}
+
+    function tfiledef.gettypename : string;
+
+      begin
+         case filetyp of
+           ft_untyped:
+             gettypename:='File';
+           ft_typed:
+             gettypename:='File Of '+typedfiletype.def^.typename;
+           ft_text:
+             gettypename:='Text'
+         end;
+      end;
+
+
+
+{****************************************************************************
+                               TPOINTERDEF
+****************************************************************************}
+
+    constructor tpointerdef.init(const tt : ttype);
+      begin
+        tdef.init;
+        deftype:=pointerdef;
+        pointertype:=tt;
+        is_far:=false;
+        savesize:=target_os.size_of_pointer;
+        pointertypeis_forwarddef:=assigned(pointertype.def) and (pointertype.def^.deftype=forwarddef);
+      end;
+
+
+    constructor tpointerdef.initfar(const tt : ttype);
+      begin
+        tdef.init;
+        deftype:=pointerdef;
+        pointertype:=tt;
+        is_far:=true;
+        savesize:=target_os.size_of_pointer;
+        pointertypeis_forwarddef:=assigned(pointertype.def) and (pointertype.def^.deftype=forwarddef);
+      end;
+
+
+    constructor tpointerdef.initdef(p : pdef);
+      var
+        t : ttype;
+      begin
+        t.setdef(p);
+        tpointerdef.init(t);
+      end;
+
+
+    constructor tpointerdef.initfardef(p : pdef);
+      var
+        t : ttype;
+      begin
+        t.setdef(p);
+        tpointerdef.initfar(t);
+      end;
+
+
+
+    constructor tpointerdef.load;
+      begin
+         tdef.load;
+         deftype:=pointerdef;
+         pointertype.load;
+         is_far:=(readbyte<>0);
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    destructor tpointerdef.done;
+      begin
+        if {assigned(pointertype.def) and
+           (pointertype.def^.deftype=forwarddef)} pointertypeis_forwarddef then
+         begin
+           dispose(pointertype.def,done);
+           pointertype.reset;
+         end;
+        inherited done;
+      end;
+
+
+    procedure tpointerdef.deref;
+      begin
+        inherited deref;
+        pointertype.resolve;
+      end;
+
+
+    procedure tpointerdef.write;
+      begin
+         inherited write;
+         pointertype.write;
+         writebyte(byte(is_far));
+         current_ppu^.writeentry(ibpointerdef);
+      end;
+
+
+{$ifdef GDB}
+    function tpointerdef.stabstring : pchar;
+      begin
+        stabstring := strpnew('*'+pointertype.def^.numberstring);
+      end;
+
+
+    procedure tpointerdef.concatstabto(asmlist : paasmoutput);
+      var st,nb : string;
+          sym_line_no : longint;
+      begin
+      if assigned(pointertype.def) and
+         (pointertype.def^.deftype=forwarddef) then
+        exit;
+
+      if ( (typesym=nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
+         (is_def_stab_written = not_written) then
+        begin
+          is_def_stab_written := being_written;
+        if assigned(pointertype.def) and
+           (pointertype.def^.deftype in [recorddef,objectdef]) then
+          begin
+            nb:=pointertype.def^.numberstring;
+            {to avoid infinite recursion in record with next-like fields }
+            if pointertype.def^.is_def_stab_written = being_written then
+              begin
+                if assigned(pointertype.def^.typesym) then
+                  begin
+                    if assigned(typesym) then
+                      begin
+                         st := typesym^.name;
+                         sym_line_no:=typesym^.fileinfo.line;
+                      end
+                    else
+                      begin
+                         st := ' ';
+                         sym_line_no:=0;
+                      end;
+                    st := '"'+st+':t'+numberstring+'=*'+nb
+                          +'=xs'+pointertype.def^.typesym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
+                    asmlist^.concat(new(pai_stabs,init(strpnew(st))));
+                    end;
+              end
+            else
+              begin
+                is_def_stab_written := not_written;
+                inherited concatstabto(asmlist);
+              end;
+            is_def_stab_written := written;
+          end
+        else
+          begin
+            if assigned(pointertype.def) then
+              forcestabto(asmlist,pointertype.def);
+            is_def_stab_written := not_written;
+            inherited concatstabto(asmlist);
+          end;
+        end;
+      end;
+{$endif GDB}
+
+    function tpointerdef.gettypename : string;
+
+      begin
+         gettypename:='^'+pointertype.def^.typename;
+      end;
+
+{****************************************************************************
+                              TCLASSREFDEF
+****************************************************************************}
+
+    constructor tclassrefdef.init(def : pdef);
+      begin
+         inherited initdef(def);
+         deftype:=classrefdef;
+      end;
+
+
+    constructor tclassrefdef.load;
+      begin
+         { be careful, tclassdefref inherits from tpointerdef }
+         tdef.load;
+         deftype:=classrefdef;
+         pointertype.load;
+         is_far:=false;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    procedure tclassrefdef.write;
+      begin
+         { be careful, tclassdefref inherits from tpointerdef }
+         tdef.write;
+         pointertype.write;
+         current_ppu^.writeentry(ibclassrefdef);
+      end;
+
+
+{$ifdef GDB}
+    function tclassrefdef.stabstring : pchar;
+      begin
+         stabstring:=strpnew(pvmtdef^.numberstring+';');
+      end;
+
+
+    procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
+      begin
+        inherited concatstabto(asmlist);
+      end;
+{$endif GDB}
+
+    function tclassrefdef.gettypename : string;
+
+      begin
+         gettypename:='Class Of '+pointertype.def^.typename;
+      end;
+
+
+{***************************************************************************
+                                   TSETDEF
+***************************************************************************}
+
+{ For i386 smallsets work,
+  for m68k there are problems
+  can be test by compiling with -dusesmallset PM }
+{$ifdef i386}
+{$define usesmallset}
+{$endif i386}
+
+    constructor tsetdef.init(s : pdef;high : longint);
+      begin
+         inherited init;
+         deftype:=setdef;
+         elementtype.setdef(s);
+{$ifdef usesmallset}
+         { small sets only working for i386 PM }
+         if high<32 then
+           begin
+            settype:=smallset;
+           {$ifdef testvarsets}
+            if aktsetalloc=0 THEN      { $PACKSET Fixed?}
+           {$endif}
+            savesize:=Sizeof(longint)
+           {$ifdef testvarsets}
+           else                       {No, use $PACKSET VALUE for rounding}
+            savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
+           {$endif}
+              ;
+          end
+         else
+{$endif usesmallset}
+         if high<256 then
+           begin
+              settype:=normset;
+              savesize:=32;
+           end
+         else
+{$ifdef testvarsets}
+         if high<$10000 then
+           begin
+              settype:=varset;
+              savesize:=4*((high+31) div 32);
+           end
+         else
+{$endif testvarsets}
+          Message(sym_e_ill_type_decl_set);
+      end;
+
+
+    constructor tsetdef.load;
+      begin
+         inherited load;
+         deftype:=setdef;
+         elementtype.load;
+         settype:=tsettype(readbyte);
+         case settype of
+            normset : savesize:=32;
+            varset : savesize:=readlong;
+            smallset : savesize:=Sizeof(longint);
+         end;
+      end;
+
+
+    destructor tsetdef.done;
+      begin
+        inherited done;
+      end;
+
+
+    procedure tsetdef.write;
+      begin
+         inherited write;
+         elementtype.write;
+         writebyte(byte(settype));
+         if settype=varset then
+           writelong(savesize);
+         current_ppu^.writeentry(ibsetdef);
+      end;
+
+
+{$ifdef GDB}
+    function tsetdef.stabstring : pchar;
+      begin
+         { For small sets write a longint, which can at least be seen
+           in the current GDB's (PFV)
+           this is obsolete with GDBPAS !!
+           and anyhow creates problems with version 4.18!! PM
+         if settype=smallset then
+           stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
+         else }
+           stabstring := strpnew('S'+elementtype.def^.numberstring);
+      end;
+
+
+    procedure tsetdef.concatstabto(asmlist : paasmoutput);
+      begin
+      if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
+          (is_def_stab_written = not_written) then
+        begin
+          if assigned(elementtype.def) then
+            forcestabto(asmlist,elementtype.def);
+          inherited concatstabto(asmlist);
+        end;
+      end;
+{$endif GDB}
+
+
+    procedure tsetdef.deref;
+      begin
+        inherited deref;
+        elementtype.resolve;
+      end;
+
+
+    procedure tsetdef.write_rtti_data;
+      begin
+         rttilist^.concat(new(pai_const,init_8bit(tkSet)));
+         write_rtti_name;
+         rttilist^.concat(new(pai_const,init_8bit(otULong)));
+         rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
+      end;
+
+
+    procedure tsetdef.write_child_rtti_data;
+      begin
+         elementtype.def^.get_rtti_label;
+      end;
+
+
+    function tsetdef.is_publishable : boolean;
+      begin
+         is_publishable:=settype=smallset;
+      end;
+
+    function tsetdef.gettypename : string;
+
+      begin
+         if assigned(elementtype.def) then
+          gettypename:='Set Of '+elementtype.def^.typename
+         else
+          gettypename:='Empty Set';
+      end;
+
+
+{***************************************************************************
+                                 TFORMALDEF
+***************************************************************************}
+
+    constructor tformaldef.init;
+      var
+         stregdef : boolean;
+      begin
+         stregdef:=registerdef;
+         registerdef:=false;
+         inherited init;
+         deftype:=formaldef;
+         registerdef:=stregdef;
+         { formaldef must be registered at unit level !! }
+         if registerdef and assigned(current_module) then
+            if assigned(current_module^.localsymtable) then
+              psymtable(current_module^.localsymtable)^.registerdef(@self)
+            else if assigned(current_module^.globalsymtable) then
+              psymtable(current_module^.globalsymtable)^.registerdef(@self);
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    constructor tformaldef.load;
+      begin
+         inherited load;
+         deftype:=formaldef;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    procedure tformaldef.write;
+      begin
+         inherited write;
+         current_ppu^.writeentry(ibformaldef);
+      end;
+
+
+{$ifdef GDB}
+    function tformaldef.stabstring : pchar;
+      begin
+      stabstring := strpnew('formal'+numberstring+';');
+      end;
+
+
+    procedure tformaldef.concatstabto(asmlist : paasmoutput);
+      begin
+      { formaldef can't be stab'ed !}
+      end;
+{$endif GDB}
+
+    function tformaldef.gettypename : string;
+
+      begin
+         gettypename:='Var';
+      end;
+
+{***************************************************************************
+                           TARRAYDEF
+***************************************************************************}
+
+    constructor tarraydef.init(l,h : longint;rd : pdef);
+      begin
+         inherited init;
+         deftype:=arraydef;
+         lowrange:=l;
+         highrange:=h;
+         rangetype.setdef(rd);
+         elementtype.reset;
+         IsVariant:=false;
+         IsConstructor:=false;
+         IsArrayOfConst:=false;
+         IsDynamicArray:=false;
+         rangenr:=0;
+      end;
+
+
+    constructor tarraydef.load;
+      begin
+         inherited load;
+         deftype:=arraydef;
+         { the addresses are calculated later }
+         elementtype.load;
+         rangetype.load;
+         lowrange:=readlong;
+         highrange:=readlong;
+         IsArrayOfConst:=boolean(readbyte);
+         IsVariant:=false;
+         IsConstructor:=false;
+{$warning FIXME!!!!!}
+         IsDynamicArray:=false;
+         rangenr:=0;
+      end;
+
+
+    function tarraydef.getrangecheckstring : string;
+      begin
+         if (cs_create_smart in aktmoduleswitches) then
+           getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
+         else
+           getrangecheckstring:='R_'+tostr(rangenr);
+      end;
+
+
+    procedure tarraydef.genrangecheck;
+      begin
+         if rangenr=0 then
+           begin
+              { generates the data for range checking }
+              getlabelnr(rangenr);
+              if (cs_create_smart in aktmoduleswitches) then
+                datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
+              else
+                datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
+              if lowrange<=highrange then
+                begin
+                  datasegment^.concat(new(pai_const,init_32bit(lowrange)));
+                  datasegment^.concat(new(pai_const,init_32bit(highrange)));
+                end
+              { for big arrays we need two bounds }
+              else
+                begin
+                  datasegment^.concat(new(pai_const,init_32bit(lowrange)));
+                  datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
+                  datasegment^.concat(new(pai_const,init_32bit($80000000)));
+                  datasegment^.concat(new(pai_const,init_32bit(highrange)));
+                end;
+           end;
+      end;
+
+
+    procedure tarraydef.deref;
+      begin
+        inherited deref;
+        elementtype.resolve;
+        rangetype.resolve;
+      end;
+
+
+    procedure tarraydef.write;
+      begin
+         inherited write;
+         elementtype.write;
+         rangetype.write;
+         writelong(lowrange);
+         writelong(highrange);
+         writebyte(byte(IsArrayOfConst));
+         current_ppu^.writeentry(ibarraydef);
+      end;
+
+
+{$ifdef GDB}
+    function tarraydef.stabstring : pchar;
+      begin
+      stabstring := strpnew('ar'+rangetype.def^.numberstring+';'
+                    +tostr(lowrange)+';'+tostr(highrange)+';'+elementtype.def^.numberstring);
+      end;
+
+
+    procedure tarraydef.concatstabto(asmlist : paasmoutput);
+      begin
+      if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
+        and (is_def_stab_written = not_written) then
+        begin
+        {when array are inserted they have no definition yet !!}
+        if assigned(elementtype.def) then
+          inherited concatstabto(asmlist);
+        end;
+      end;
+{$endif GDB}
+
+
+    function tarraydef.elesize : longint;
+      begin
+        if isconstructor or is_open_array(@self) then
+         begin
+           { strings are stored by address only }
+           case elementtype.def^.deftype of
+             stringdef :
+               elesize:=4;
+             else
+               elesize:=elementtype.def^.size;
+           end;
+         end
+        else
+         elesize:=elementtype.def^.size;
+      end;
+
+
+    function tarraydef.size : longint;
+      begin
+        {Tarraydef.size may never be called for an open array!}
+        if IsDynamicArray then
+          begin
+             size:=4;
+             exit;
+          end;
+        if highrange<lowrange then
+            internalerror(99080501);
+        If (elesize>0) and
+           (
+            (highrange-lowrange = $7fffffff) or
+            { () are needed around elesize-1 to avoid a possible
+              integer overflow for elesize=1 !! PM }
+            (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
+           ) Then
+          Begin
+            Message(sym_e_segment_too_large);
+            size := 4
+          End
+        Else size:=(highrange-lowrange+1)*elesize;
+      end;
+
+
+    function tarraydef.alignment : longint;
+      begin
+         { alignment is the size of the elements }
+         if elementtype.def^.deftype=recorddef then
+          alignment:=elementtype.def^.alignment
+         else
+          alignment:=elesize;
+      end;
+
+
+    function tarraydef.needs_inittable : boolean;
+      begin
+         needs_inittable:=IsDynamicArray or elementtype.def^.needs_inittable;
+      end;
+
+
+    procedure tarraydef.write_child_rtti_data;
+      begin
+         elementtype.def^.get_rtti_label;
+      end;
+
+
+    procedure tarraydef.write_rtti_data;
+      begin
+         if IsDynamicArray then
+           rttilist^.concat(new(pai_const,init_8bit(tkdynarray)))
+         else
+           rttilist^.concat(new(pai_const,init_8bit(tkarray)));
+         write_rtti_name;
+         { size of elements }
+         rttilist^.concat(new(pai_const,init_32bit(elesize)));
+         { count of elements }
+         if not(IsDynamicArray) then
+           rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
+         { element type }
+         rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
+         { variant type }
+         // !!!!!!!!!!!!!!!!
+      end;
+
+    function tarraydef.gettypename : string;
+
+      begin
+         if isarrayofconst or isConstructor then
+           begin
+             if isvariant or ((highrange=-1) and (lowrange=0)) then
+               gettypename:='Array Of Const'
+             else
+               gettypename:='Array Of '+elementtype.def^.typename;
+           end
+         else if is_open_array(@self) or IsDynamicArray then
+           gettypename:='Array Of '+elementtype.def^.typename
+         else
+           begin
+              if rangetype.def^.deftype=enumdef then
+                gettypename:='Array['+rangetype.def^.typename+'] Of '+elementtype.def^.typename
+              else
+                gettypename:='Array['+tostr(lowrange)+'..'+
+                  tostr(highrange)+'] Of '+elementtype.def^.typename
+           end;
+      end;
+
+{***************************************************************************
+                                  trecorddef
+***************************************************************************}
+
+    constructor trecorddef.init(p : psymtable);
+      begin
+         inherited init;
+         deftype:=recorddef;
+         symtable:=p;
+         symtable^.defowner := @self;
+         symtable^.dataalignment:=packrecordalignment[aktpackrecords];
+      end;
+
+
+    constructor trecorddef.load;
+      var
+         oldread_member : boolean;
+      begin
+         inherited load;
+         deftype:=recorddef;
+         savesize:=readlong;
+         oldread_member:=read_member;
+         read_member:=true;
+         symtable:=new(psymtable,loadas(recordsymtable));
+         read_member:=oldread_member;
+         symtable^.defowner := @self;
+      end;
+
+
+    destructor trecorddef.done;
+      begin
+         if assigned(symtable) then
+           dispose(symtable,done);
+         inherited done;
+      end;
+
+
+    var
+       binittable : boolean;
+
+    procedure check_rec_inittable(s : pnamedindexobject);
+
+      begin
+         if (not binittable) and
+            (psym(s)^.typ=varsym) and
+            assigned(pvarsym(s)^.vartype.def) then
+          begin
+            if (pvarsym(s)^.vartype.def^.deftype<>objectdef) or
+               not is_class(pvarsym(s)^.vartype.def) then
+             binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
+          end;
+      end;
+
+
+    function trecorddef.needs_inittable : boolean;
+      var
+         oldb : boolean;
+      begin
+         { there are recursive calls to needs_rtti possible, }
+         { so we have to change to old value how else should }
+         { we do that ? check_rec_rtti can't be a nested     }
+         { procedure of needs_rtti !                         }
+         oldb:=binittable;
+         binittable:=false;
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
+         needs_inittable:=binittable;
+         binittable:=oldb;
+      end;
+
+
+    procedure trecorddef.deref;
+      var
+         oldrecsyms : psymtable;
+      begin
+         inherited deref;
+         oldrecsyms:=aktrecordsymtable;
+         aktrecordsymtable:=symtable;
+         { now dereference the definitions }
+         symtable^.deref;
+         aktrecordsymtable:=oldrecsyms;
+      end;
+
+
+    procedure trecorddef.write;
+      var
+         oldread_member : boolean;
+      begin
+         oldread_member:=read_member;
+         read_member:=true;
+         inherited write;
+         writelong(savesize);
+         current_ppu^.writeentry(ibrecorddef);
+         self.symtable^.writeas;
+         read_member:=oldread_member;
+      end;
+
+    function trecorddef.size:longint;
+      begin
+        size:=symtable^.datasize;
+      end;
+
+
+    function trecorddef.alignment:longint;
+      var
+        l  : longint;
+        hp : pvarsym;
+      begin
+        { also check the first symbol for it's size, because a
+          packed record has dataalignment of 1, but the first
+          sym could be a longint which should be aligned on 4 bytes,
+          this is compatible with C record packing (PFV) }
+        hp:=pvarsym(symtable^.symindex^.first);
+        if assigned(hp) then
+         begin
+           l:=hp^.vartype.def^.size;
+           if l>symtable^.dataalignment then
+            begin
+              if l>=4 then
+               alignment:=4
+              else
+               if l>=2 then
+                alignment:=2
+              else
+               alignment:=1;
+            end
+           else
+            alignment:=symtable^.dataalignment;
+         end
+        else
+         alignment:=symtable^.dataalignment;
+      end;
+
+{$ifdef GDB}
+    Const StabRecString : pchar = Nil;
+          StabRecSize : longint = 0;
+          RecOffset : Longint = 0;
+
+    procedure addname(p : pnamedindexobject);
+    var
+      news, newrec : pchar;
+      spec : string[3];
+      size : longint;
+    begin
+    { static variables from objects are like global objects }
+    if (sp_static in psym(p)^.symoptions) then
+      exit;
+    If psym(p)^.typ = varsym then
+       begin
+         if (sp_protected in psym(p)^.symoptions) then
+           spec:='/1'
+         else if (sp_private in psym(p)^.symoptions) then
+           spec:='/0'
+         else
+           spec:='';
+         if not assigned(pvarsym(p)^.vartype.def) then
+          writeln(pvarsym(p)^.name);
+         { class fields are pointers PM, obsolete now PM }
+         {if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
+            pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
+            spec:=spec+'*'; }
+         size:=pvarsym(p)^.vartype.def^.size;
+         { open arrays made overflows !! }
+         if size>$fffffff then
+           size:=$fffffff;
+         newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.vartype.def^.numberstring
+                       +','+tostr(pvarsym(p)^.address*8)+','
+                       +tostr(size*8)+';');
+         if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
+           begin
+              getmem(news,stabrecsize+memsizeinc);
+              strcopy(news,stabrecstring);
+              freemem(stabrecstring,stabrecsize);
+              stabrecsize:=stabrecsize+memsizeinc;
+              stabrecstring:=news;
+           end;
+         strcat(StabRecstring,newrec);
+         strdispose(newrec);
+         {This should be used for case !!}
+         RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;
+       end;
+    end;
+
+
+    function trecorddef.stabstring : pchar;
+      Var oldrec : pchar;
+          oldsize : longint;
+      begin
+        oldrec := stabrecstring;
+        oldsize:=stabrecsize;
+        GetMem(stabrecstring,memsizeinc);
+        stabrecsize:=memsizeinc;
+        strpcopy(stabRecString,'s'+tostr(size));
+        RecOffset := 0;
+        symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
+        { FPC doesn't want to convert a char to a pchar}
+        { is this a bug ? }
+        strpcopy(strend(StabRecString),';');
+        stabstring := strnew(StabRecString);
+        Freemem(stabrecstring,stabrecsize);
+        stabrecstring := oldrec;
+        stabrecsize:=oldsize;
+      end;
+
+
+    procedure trecorddef.concatstabto(asmlist : paasmoutput);
+      begin
+        if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
+           (is_def_stab_written = not_written)  then
+          inherited concatstabto(asmlist);
+      end;
+
+{$endif GDB}
+
+    var
+       count : longint;
+
+    procedure count_inittable_fields(sym : pnamedindexobject);
+      begin
+         if ((psym(sym)^.typ=varsym) and
+            pvarsym(sym)^.vartype.def^.needs_inittable)
+            and ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
+                  not(is_class(pvarsym(sym)^.vartype.def))) then
+           inc(count);
+      end;
+
+
+    procedure count_fields(sym : pnamedindexobject);
+      begin
+            inc(count);
+      end;
+
+
+    procedure write_field_inittable(sym : pnamedindexobject);
+      begin
+         if ((psym(sym)^.typ=varsym) and
+            pvarsym(sym)^.vartype.def^.needs_inittable) and
+            ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
+             not(is_class(pvarsym(sym)^.vartype.def))) then
+           begin
+              rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.vartype.def^.get_inittable_label)));
+              rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
+           end;
+      end;
+
+
+    procedure write_field_rtti(sym : pnamedindexobject);
+      begin
+         rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
+         rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
+      end;
+
+
+    procedure generate_child_inittable(sym:pnamedindexobject);
+      begin
+         if (psym(sym)^.typ=varsym) and
+            pvarsym(sym)^.vartype.def^.needs_inittable then
+         { force inittable generation }
+           pvarsym(sym)^.vartype.def^.get_inittable_label;
+      end;
+
+
+    procedure generate_child_rtti(sym : pnamedindexobject);
+      begin
+         pvarsym(sym)^.vartype.def^.get_rtti_label;
+      end;
+
+
+    procedure trecorddef.write_child_rtti_data;
+      begin
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_rtti);
+      end;
+
+
+    procedure trecorddef.write_child_init_data;
+      begin
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
+      end;
+
+
+    procedure trecorddef.write_rtti_data;
+      begin
+         rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
+         write_rtti_name;
+         rttilist^.concat(new(pai_const,init_32bit(size)));
+         count:=0;
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_fields);
+         rttilist^.concat(new(pai_const,init_32bit(count)));
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
+      end;
+
+
+    procedure trecorddef.write_init_data;
+      begin
+         rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
+         write_rtti_name;
+         rttilist^.concat(new(pai_const,init_32bit(size)));
+         count:=0;
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
+         rttilist^.concat(new(pai_const,init_32bit(count)));
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
+      end;
+
+    function trecorddef.gettypename : string;
+
+      begin
+         gettypename:='<record type>'
+      end;
+
+
+{***************************************************************************
+                       TABSTRACTPROCDEF
+***************************************************************************}
+
+    constructor tabstractprocdef.init;
+      begin
+         inherited init;
+         new(para,init);
+         minparacount:=0;
+         maxparacount:=0;
+         fpu_used:=0;
+         proctypeoption:=potype_none;
+         proccalloptions:=[];
+         procoptions:=[];
+         rettype.setdef(voiddef);
+         symtablelevel:=0;
+         savesize:=target_os.size_of_pointer;
+      end;
+
+
+    destructor tabstractprocdef.done;
+      begin
+         dispose(para,done);
+         inherited done;
+      end;
+
+
+    procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez;defval:psym);
+      var
+        hp : pparaitem;
+      begin
+        new(hp,init);
+        hp^.paratyp:=vsp;
+        hp^.paratype:=tt;
+        hp^.register:=R_NO;
+        hp^.defaultvalue:=defval;
+        para^.insert(hp);
+        if not assigned(defval) then
+         inc(minparacount);
+        inc(maxparacount);
+      end;
+
+
+    { all functions returning in FPU are
+      assume to use 2 FPU registers
+      until the function implementation
+      is processed   PM }
+    procedure tabstractprocdef.test_if_fpu_result;
+      begin
+         if assigned(rettype.def) and is_fpu(rettype.def) then
+           fpu_used:=2;
+      end;
+
+
+    procedure tabstractprocdef.deref;
+      var
+         hp : pparaitem;
+      begin
+         inherited deref;
+         rettype.resolve;
+         hp:=pparaitem(para^.first);
+         while assigned(hp) do
+          begin
+            hp^.paratype.resolve;
+            resolvesym(psym(hp^.defaultvalue));
+            hp:=pparaitem(hp^.next);
+          end;
+      end;
+
+
+    constructor tabstractprocdef.load;
+      var
+         hp : pparaitem;
+         count,i : word;
+      begin
+         inherited load;
+         new(para,init);
+         minparacount:=0;
+         maxparacount:=0;
+         rettype.load;
+         fpu_used:=readbyte;
+         proctypeoption:=tproctypeoption(readlong);
+         readsmallset(proccalloptions,sizeof(proccalloptions));
+         readsmallset(procoptions,sizeof(procoptions));
+         count:=readword;
+         savesize:=target_os.size_of_pointer;
+         for i:=1 to count do
+          begin
+            new(hp,init);
+            hp^.paratyp:=tvarspez(readbyte);
+            { hp^.register:=tregister(readbyte); }
+            hp^.register:=R_NO;
+            hp^.paratype.load;
+            hp^.defaultvalue:=readsymref;
+            if not assigned(hp^.defaultvalue) then
+             inc(minparacount);
+            inc(maxparacount);
+            para^.concat(hp);
+          end;
+      end;
+
+
+    procedure tabstractprocdef.write;
+      var
+        hp : pparaitem;
+        oldintfcrc : boolean;
+      begin
+         inherited write;
+         rettype.write;
+         oldintfcrc:=current_ppu^.do_interface_crc;
+         current_ppu^.do_interface_crc:=false;
+         writebyte(fpu_used);
+         writelong(ord(proctypeoption));
+         writesmallset(proccalloptions,sizeof(proccalloptions));
+         writesmallset(procoptions,sizeof(procoptions));
+         current_ppu^.do_interface_crc:=oldintfcrc;
+         writeword(maxparacount);
+         hp:=pparaitem(para^.first);
+         while assigned(hp) do
+          begin
+            writebyte(byte(hp^.paratyp));
+            { writebyte(byte(hp^.register)); }
+            hp^.paratype.write;
+            writesymref(hp^.defaultvalue);
+            hp:=pparaitem(hp^.next);
+          end;
+      end;
+
+
+    function tabstractprocdef.para_size(alignsize:longint) : longint;
+      var
+         pdc : pparaitem;
+         l : longint;
+      begin
+         l:=0;
+         pdc:=pparaitem(para^.first);
+         while assigned(pdc) do
+          begin
+            case pdc^.paratyp of
+              vs_out,
+              vs_var   : inc(l,target_os.size_of_pointer);
+              vs_value,
+              vs_const : if push_addr_param(pdc^.paratype.def) then
+                          inc(l,target_os.size_of_pointer)
+                         else
+                          inc(l,pdc^.paratype.def^.size);
+            end;
+            l:=align(l,alignsize);
+            pdc:=pparaitem(pdc^.next);
+          end;
+         para_size:=l;
+      end;
+
+
+    function tabstractprocdef.demangled_paras : string;
+      var
+        hs,s : string;
+        hp : pparaitem;
+        hpc : pconstsym;
+      begin
+        s:='(';
+        hp:=pparaitem(para^.last);
+        while assigned(hp) do
+         begin
+           if assigned(hp^.paratype.def^.typesym) then
+             s:=s+hp^.paratype.def^.typesym^.name
+           else if hp^.paratyp=vs_out then
+             s:=s+'out'
+           else if hp^.paratyp=vs_var then
+             s:=s+'var'
+           else if hp^.paratyp=vs_const then
+             s:=s+'const'
+           else if hp^.paratyp=vs_out then
+             s:=s+'out';
+           { default value }
+           if assigned(hp^.defaultvalue) then
+            begin
+              hpc:=pconstsym(hp^.defaultvalue);
+              hs:='';
+              case hpc^.consttyp of
+                conststring,
+                constresourcestring :
+                  hs:=strpas(pchar(tpointerord(hpc^.value)));
+                constreal :
+                  str(pbestreal(tpointerord(hpc^.value))^,hs);
+                constord,
+                constpointer :
+                  hs:=tostr(hpc^.value);
+                constbool :
+                  begin
+                    if hpc^.value<>0 then
+                     hs:='TRUE'
+                    else
+                     hs:='FALSE';
+                  end;
+                constnil :
+                  hs:='nil';
+                constchar :
+                  hs:=chr(hpc^.value);
+                constset :
+                  hs:='<set>';
+              end;
+              if hs<>'' then
+               s:=s+'="'+hs+'"';
+            end;
+           hp:=pparaitem(hp^.previous);
+           if assigned(hp) then
+            s:=s+',';
+         end;
+        s:=s+')';
+        demangled_paras:=s;
+      end;
+
+
+    function tabstractprocdef.proccalloption2str : string;
+      type
+        tproccallopt=record
+          mask : tproccalloption;
+          str  : string[30];
+        end;
+      const
+        proccallopts=13;
+        proccallopt : array[1..proccallopts] of tproccallopt=(
+           (mask:pocall_none;         str:''),
+           (mask:pocall_clearstack;   str:'ClearStack'),
+           (mask:pocall_leftright;    str:'LeftRight'),
+           (mask:pocall_cdecl;        str:'CDecl'),
+           (mask:pocall_register;     str:'Register'),
+           (mask:pocall_stdcall;      str:'StdCall'),
+           (mask:pocall_safecall;     str:'SafeCall'),
+           (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
+           (mask:pocall_system;       str:'System'),
+           (mask:pocall_inline;       str:'Inline'),
+           (mask:pocall_internproc;   str:'InternProc'),
+           (mask:pocall_internconst;  str:'InternConst'),
+           (mask:pocall_cdecl;        str:'CPPDecl')
+        );
+      var
+        s : string;
+        i : longint;
+        first : boolean;
+      begin
+        s:='';
+        first:=true;
+        for i:=1to proccallopts do
+         if (proccallopt[i].mask in proccalloptions) then
+          begin
+            if first then
+              first:=false
+            else
+              s:=s+';';
+            s:=s+proccallopt[i].str;
+          end;
+        proccalloption2str:=s;
+      end;
+
+
+{$ifdef GDB}
+    function tabstractprocdef.stabstring : pchar;
+      begin
+        stabstring := strpnew('abstractproc'+numberstring+';');
+      end;
+
+
+    procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
+      begin
+         if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
+            and (is_def_stab_written = not_written)  then
+           begin
+              if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
+              inherited concatstabto(asmlist);
+           end;
+      end;
+{$endif GDB}
+
+
+{***************************************************************************
+                                  TPROCDEF
+***************************************************************************}
+
+    constructor tprocdef.init;
+      begin
+         inherited init;
+         deftype:=procdef;
+         _mangledname:=nil;
+         nextoverloaded:=nil;
+         fileinfo:=aktfilepos;
+         extnumber:=-1;
+         localst:=new(psymtable,init(localsymtable));
+         parast:=new(psymtable,init(parasymtable));
+         localst^.defowner:=@self;
+         parast^.defowner:=@self;
+         { this is used by insert
+          to check same names in parast and localst }
+         localst^.next:=parast;
+         defref:=nil;
+         crossref:=nil;
+         lastwritten:=nil;
+         refcount:=0;
+         if (cs_browser in aktmoduleswitches) and make_ref then
+          begin
+            defref:=new(pref,init(defref,@tokenpos));
+            inc(refcount);
+          end;
+         lastref:=defref;
+       { first, we assume that all registers are used }
+{$ifdef newcg}
+         usedregisters:=[firstreg..lastreg];
+{$else newcg}
+{$ifdef i386}
+         usedregisters:=$ff;
+{$endif i386}
+{$ifdef m68k}
+         usedregisters:=$FFFF;
+{$endif}
+{$endif newcg}
+         forwarddef:=true;
+         interfacedef:=false;
+         hasforward:=false;
+         _class := nil;
+         code:=nil;
+         regvarinfo := nil;
+         count:=false;
+         is_used:=false;
+      end;
+
+
+    constructor tprocdef.load;
+      begin
+         inherited load;
+         deftype:=procdef;
+
+{$ifdef newcg}
+         readnormalset(usedregisters);
+{$else newcg}
+{$ifdef i386}
+         usedregisters:=readbyte;
+{$endif i386}
+{$ifdef m68k}
+         usedregisters:=readword;
+{$endif}
+{$endif newcg}
+         _mangledname:=stringdup(readstring);
+
+         extnumber:=readlong;
+         nextoverloaded:=pprocdef(readdefref);
+         _class := pobjectdef(readdefref);
+         readposinfo(fileinfo);
+
+         procsym:=pprocsym(readsymref);
+
+         if (cs_link_deffile in aktglobalswitches) and
+            (tf_need_export in target_info.flags) and
+            (po_exports in procoptions) then
+           deffile.AddExport(mangledname);
+
+         new(parast,loadas(parasymtable));
+         parast^.defowner:=@self;
+         {new(localst,loadas(localsymtable));
+         localst^.defowner:=@self;
+         parast^.next:=localst;
+         localst^.next:=owner;}
+
+         forwarddef:=false;
+         interfacedef:=false;
+         hasforward:=false;
+         code := nil;
+         regvarinfo := nil;
+         lastref:=nil;
+         lastwritten:=nil;
+         defref:=nil;
+         refcount:=0;
+         count:=true;
+         is_used:=false;
+      end;
+
+
+Const local_symtable_index : longint = $8001;
+
+    procedure tprocdef.load_references;
+      var
+        pos : tfileposinfo;
+{$ifndef NOLOCALBROWSER}
+        oldsymtablestack,
+        st : psymtable;
+{$endif ndef NOLOCALBROWSER}
+        move_last : boolean;
+      begin
+        move_last:=lastwritten=lastref;
+        while (not current_ppu^.endofentry) do
+         begin
+           readposinfo(pos);
+           inc(refcount);
+           lastref:=new(pref,init(lastref,@pos));
+           lastref^.is_written:=true;
+           if refcount=1 then
+            defref:=lastref;
+         end;
+        if move_last then
+          lastwritten:=lastref;
+        if ((current_module^.flags and uf_local_browser)<>0)
+           and is_in_current then
+          begin
+{$ifndef NOLOCALBROWSER}
+             oldsymtablestack:=symtablestack;
+             st:=aktlocalsymtable;
+             new(parast,loadas(parasymtable));
+             parast^.defowner:=@self;
+             aktlocalsymtable:=parast;
+             parast^.deref;
+             parast^.next:=owner;
+             parast^.load_browser;
+             aktlocalsymtable:=st;
+             new(localst,loadas(localsymtable));
+             localst^.defowner:=@self;
+             aktlocalsymtable:=localst;
+             symtablestack:=parast;
+             localst^.deref;
+             localst^.next:=parast;
+             localst^.load_browser;
+             aktlocalsymtable:=st;
+             symtablestack:=oldsymtablestack;
+{$endif ndef NOLOCALBROWSER}
+          end;
+      end;
+
+
+    function tprocdef.write_references : boolean;
+      var
+        ref : pref;
+{$ifndef NOLOCALBROWSER}
+        st : psymtable;
+        pdo : pobjectdef;
+{$endif ndef NOLOCALBROWSER}
+        move_last : boolean;
+      begin
+        move_last:=lastwritten=lastref;
+        if move_last and (((current_module^.flags and uf_local_browser)=0)
+           or not is_in_current) then
+          exit;
+      { write address of this symbol }
+        writedefref(@self);
+      { write refs }
+        if assigned(lastwritten) then
+          ref:=lastwritten
+        else
+          ref:=defref;
+        while assigned(ref) do
+         begin
+           if ref^.moduleindex=current_module^.unit_index then
+             begin
+                writeposinfo(ref^.posinfo);
+                ref^.is_written:=true;
+                if move_last then
+                  lastwritten:=ref;
+             end
+           else if not ref^.is_written then
+             move_last:=false
+           else if move_last then
+             lastwritten:=ref;
+           ref:=ref^.nextref;
+         end;
+        current_ppu^.writeentry(ibdefref);
+        write_references:=true;
+        if ((current_module^.flags and uf_local_browser)<>0)
+           and is_in_current then
+          begin
+{$ifndef NOLOCALBROWSER}
+             pdo:=_class;
+             if (owner^.symtabletype<>localsymtable) then
+               while assigned(pdo) do
+                 begin
+                    if pdo^.symtable<>aktrecordsymtable then
+                      begin
+                         pdo^.symtable^.unitid:=local_symtable_index;
+                         inc(local_symtable_index);
+                      end;
+                    pdo:=pdo^.childof;
+                 end;
+
+             { we need TESTLOCALBROWSER para and local symtables
+               PPU files are then easier to read PM }
+             if not assigned(parast) then
+               parast:=new(psymtable,init(parasymtable));
+             parast^.defowner:=@self;
+             st:=aktlocalsymtable;
+             aktlocalsymtable:=parast;
+             parast^.writeas;
+             parast^.unitid:=local_symtable_index;
+             inc(local_symtable_index);
+             parast^.write_browser;
+             if not assigned(localst) then
+               localst:=new(psymtable,init(localsymtable));
+             localst^.defowner:=@self;
+             aktlocalsymtable:=localst;
+             localst^.writeas;
+             localst^.unitid:=local_symtable_index;
+             inc(local_symtable_index);
+             localst^.write_browser;
+             aktlocalsymtable:=st;
+             { decrement for }
+             local_symtable_index:=local_symtable_index-2;
+             pdo:=_class;
+             if (owner^.symtabletype<>localsymtable) then
+               while assigned(pdo) do
+                 begin
+                    if pdo^.symtable<>aktrecordsymtable then
+                      dec(local_symtable_index);
+                    pdo:=pdo^.childof;
+                 end;
+{$endif ndef NOLOCALBROWSER}
+          end;
+      end;
+
+
+{$ifdef BrowserLog}
+    procedure tprocdef.add_to_browserlog;
+      begin
+         if assigned(defref) then
+          begin
+            browserlog.AddLog('***'+mangledname);
+            browserlog.AddLogRefs(defref);
+            if (current_module^.flags and uf_local_browser)<>0 then
+              begin
+                 if assigned(parast) then
+                   parast^.writebrowserlog;
+                 if assigned(localst) then
+                   localst^.writebrowserlog;
+              end;
+          end;
+      end;
+{$endif BrowserLog}
+
+
+    destructor tprocdef.done;
+      begin
+         if assigned(defref) then
+           begin
+             defref^.freechain;
+             dispose(defref,done);
+           end;
+         if assigned(parast) then
+           dispose(parast,done);
+         if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
+           dispose(localst,done);
+         if (pocall_inline in proccalloptions) and assigned(code) then
+           tnode(code).free;
+         if assigned(regvarinfo) then
+           dispose(pregvarinfo(regvarinfo));
+         if (po_msgstr in procoptions) then
+           strdispose(messageinf.str);
+         if assigned(_mangledname) then
+           stringdispose(_mangledname);
+         inherited done;
+      end;
+
+
+    procedure tprocdef.write;
+      var
+        oldintfcrc : boolean;
+      begin
+         inherited write;
+         oldintfcrc:=current_ppu^.do_interface_crc;
+         current_ppu^.do_interface_crc:=false;
+   { set all registers to used for simplified compilation PM }
+         if simplify_ppu then
+           begin
+{$ifdef newcg}
+             usedregisters:=[firstreg..lastreg];
+{$else newcg}
+{$ifdef i386}
+             usedregisters:=$ff;
+{$endif i386}
+{$ifdef m68k}
+             usedregisters:=$ffff;
+{$endif}
+{$endif newcg}
+           end;
+
+{$ifdef newcg}
+         writenormalset(usedregisters);
+{$else newcg}
+{$ifdef i386}
+         writebyte(usedregisters);
+{$endif i386}
+{$ifdef m68k}
+         writeword(usedregisters);
+{$endif}
+{$endif newcg}
+         current_ppu^.do_interface_crc:=oldintfcrc;
+         writestring(mangledname);
+         writelong(extnumber);
+         if (proctypeoption<>potype_operator) then
+           writedefref(nextoverloaded)
+         else
+           begin
+              { only write the overloads from the same unit }
+              if assigned(nextoverloaded) and
+                 (nextoverloaded^.owner=owner) then
+                writedefref(nextoverloaded)
+              else
+                writedefref(nil);
+           end;
+         writedefref(_class);
+         writeposinfo(fileinfo);
+         writesymref(procsym);
+         if (pocall_inline in proccalloptions) then
+           begin
+              { we need to save
+                - the para and the local symtable
+                - the code ptree !! PM
+               writesymtable(parast);
+               writesymtable(localst);
+               writeptree(ptree(code));
+               }
+           end;
+         current_ppu^.writeentry(ibprocdef);
+
+         { Save the para and local symtable, for easier reading
+           save both always, they don't influence the interface crc }
+         oldintfcrc:=current_ppu^.do_interface_crc;
+         current_ppu^.do_interface_crc:=false;
+         if not assigned(parast) then
+          begin
+            parast:=new(psymtable,init(parasymtable));
+            parast^.defowner:=@self;
+          end;
+         parast^.writeas;
+         {if not assigned(localst) then
+          begin
+            localst:=new(psymtable,init(localsymtable));
+            localst^.defowner:=@self;
+          end;
+         localst^.writeas;}
+         current_ppu^.do_interface_crc:=oldintfcrc;
+      end;
+
+
+    function tprocdef.haspara:boolean;
+      begin
+        haspara:=assigned(aktprocsym^.definition^.parast^.symindex^.first);
+      end;
+
+
+{$ifdef GDB}
+    procedure addparaname(p : psym);
+      var vs : char;
+      begin
+      if pvarsym(p)^.varspez = vs_value then vs := '1'
+        else vs := '0';
+      strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.vartype.def^.numberstring+','+vs+';');
+      end;
+
+
+    function tprocdef.stabstring : pchar;
+      var
+          i : longint;
+          oldrec : pchar;
+      begin
+      oldrec := stabrecstring;
+      getmem(StabRecString,1024);
+      strpcopy(StabRecString,'f'+rettype.def^.numberstring);
+      i:=maxparacount;
+      if i>0 then
+        begin
+        strpcopy(strend(StabRecString),','+tostr(i)+';');
+        (* confuse gdb !! PM
+        if assigned(parast) then
+          parast^.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
+          else
+          begin
+          param := para1;
+          i := 0;
+          while assigned(param) do
+            begin
+            inc(i);
+            if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
+            {Here we have lost the parameter names !!}
+            {using lower case parameters }
+            strpcopy(strend(stabrecstring),'p'+tostr(i)
+               +':'+param^.paratype.def^.numberstring+','+vartyp+';');
+            param := param^.next;
+            end;
+          end;   *)
+        {strpcopy(strend(StabRecString),';');}
+        end;
+      stabstring := strnew(stabrecstring);
+      freemem(stabrecstring,1024);
+      stabrecstring := oldrec;
+      end;
+
+
+    procedure tprocdef.concatstabto(asmlist : paasmoutput);
+      begin
+      end;
+{$endif GDB}
+
+
+    procedure tprocdef.deref;
+      var
+        oldsymtablestack,
+        oldlocalsymtable : psymtable;
+      begin
+         inherited deref;
+         resolvedef(pdef(nextoverloaded));
+         resolvedef(pdef(_class));
+         { parast }
+         oldsymtablestack:=symtablestack;
+         oldlocalsymtable:=aktlocalsymtable;
+         aktlocalsymtable:=parast;
+         parast^.deref;
+         {symtablestack:=parast;
+         aktlocalsymtable:=localst;
+         localst^.deref;}
+         aktlocalsymtable:=oldlocalsymtable;
+         symtablestack:=oldsymtablestack;
+      end;
+
+
+    function tprocdef.mangledname : string;
+      begin
+         if assigned(_mangledname) then
+           mangledname:=_mangledname^
+         else
+           mangledname:='';
+         if count then
+           is_used:=true;
+      end;
+
+
+{$ifdef dummy}
+    function tprocdef.procname: string;
+      var
+        s : string;
+        l : longint;
+      begin
+         if assigned(procsym) then
+           begin
+             procname:=procsym^.name;
+             exit;
+           end;
+         s:=mangledname;
+         { delete leading $$'s }
+         l:=pos('$$',s);
+         while l<>0 do
+           begin
+              delete(s,1,l+1);
+              l:=pos('$$',s);
+           end;
+         { delete leading _$'s }
+         l:=pos('_$',s);
+         while l<>0 do
+           begin
+              delete(s,1,l+1);
+              l:=pos('_$',s);
+           end;
+         l:=pos('$',s);
+         if l=0 then
+          procname:=s
+         else
+          procname:=Copy(s,1,l-1);
+      end;
+{$endif}
+
+    function tprocdef.cplusplusmangledname : string;
+
+      function getcppparaname(p : pdef) : string;
+
+        const
+           ordtype2str : array[tbasetype] of string[2] = (
+             '','','c',
+             'Uc','Us','Ui',
+             'Sc','s','i',
+             'b','b','b',
+             'Us','x','w');
+
+        var
+           s : string;
+
+        begin
+           case p^.deftype of
+              orddef:
+                s:=ordtype2str[porddef(p)^.typ];
+              pointerdef:
+                s:='P'+getcppparaname(ppointerdef(p)^.pointertype.def);
+              else
+                internalerror(2103001);
+           end;
+           getcppparaname:=s;
+        end;
+
+      var
+         s,s2 : string;
+         param : pparaitem;
+
+      begin
+         s := procsym^.realname;
+         if procsym^.owner^.symtabletype=objectsymtable then
+           begin
+              s2:=upper(pobjectdef(procsym^.owner^.defowner)^.typesym^.realname);
+              case proctypeoption of
+                 potype_destructor:
+                   s:='_$_'+tostr(length(s2))+s2;
+                 potype_constructor:
+                   s:='___'+tostr(length(s2))+s2;
+                 else
+                   s:='_'+s+'__'+tostr(length(s2))+s2;
+              end;
+
+           end
+         else s:=s+'__';
+
+         s:=s+'F';
+
+         { concat modifiers }
+         { !!!!! }
+
+         { now we handle the parameters }
+         param := pparaitem(para^.first);
+         if assigned(param) then
+           while assigned(param) do
+             begin
+                s2:=getcppparaname(param^.paratype.def);
+                if param^.paratyp in [vs_var,vs_out] then
+                  s2:='R'+s2;
+                s:=s+s2;
+                param:=pparaitem(param^.next);
+             end
+         else
+           s:=s+'v';
+         cplusplusmangledname:=s;
+      end;
+
+    procedure tprocdef.setmangledname(const s : string);
+      begin
+         if assigned(_mangledname) then
+           begin
+{$ifdef MEMDEBUG}
+              dec(manglenamesize,length(_mangledname^));
+{$endif}
+              stringdispose(_mangledname);
+           end;
+         _mangledname:=stringdup(s);
+{$ifdef MEMDEBUG}
+         inc(manglenamesize,length(s));
+{$endif}
+{$ifdef EXTDEBUG}
+         if assigned(parast) then
+           begin
+              stringdispose(parast^.name);
+              parast^.name:=stringdup('args of '+s);
+           end;
+         if assigned(localst) then
+           begin
+              stringdispose(localst^.name);
+              localst^.name:=stringdup('locals of '+s);
+           end;
+{$endif}
+      end;
+
+
+{***************************************************************************
+                                 TPROCVARDEF
+***************************************************************************}
+
+    constructor tprocvardef.init;
+      begin
+         inherited init;
+         deftype:=procvardef;
+      end;
+
+
+    constructor tprocvardef.load;
+      begin
+         inherited load;
+         deftype:=procvardef;
+      end;
+
+
+    procedure tprocvardef.write;
+      begin
+         { here we cannot get a real good value so just give something }
+         { plausible (PM) }
+         { a more secure way would be
+           to allways store in a temp }
+         if is_fpu(rettype.def) then
+           fpu_used:=2
+         else
+           fpu_used:=0;
+         inherited write;
+         current_ppu^.writeentry(ibprocvardef);
+      end;
+
+
+    function tprocvardef.size : longint;
+      begin
+         if (po_methodpointer in procoptions) then
+           size:=2*target_os.size_of_pointer
+         else
+           size:=target_os.size_of_pointer;
+      end;
+
+
+{$ifdef GDB}
+    function tprocvardef.stabstring : pchar;
+      var
+         nss : pchar;
+        { i   : longint; }
+      begin
+        { i := maxparacount; }
+        getmem(nss,1024);
+        { it is not a function but a function pointer !! (PM) }
+
+        strpcopy(nss,'*f'+rettype.def^.numberstring{+','+tostr(i)}+';');
+        { this confuses gdb !!
+          we should use 'F' instead of 'f' but
+          as we use c++ language mode
+          it does not like that either
+          Please do not remove this part
+          might be used once
+          gdb for pascal is ready PM }
+        (*
+        param := para1;
+        i := 0;
+        while assigned(param) do
+          begin
+          inc(i);
+                   vs_out  : paraspec := pfOut;
+          if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
+          {Here we have lost the parameter names !!}
+          pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
+          strcat(nss,pst);
+          strdispose(pst);
+          param := param^.next;
+          end; *)
+        {strpcopy(strend(nss),';');}
+        stabstring := strnew(nss);
+        freemem(nss,1024);
+      end;
+
+
+    procedure tprocvardef.concatstabto(asmlist : paasmoutput);
+      begin
+         if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
+           and (is_def_stab_written = not_written)  then
+           inherited concatstabto(asmlist);
+         is_def_stab_written:=written;
+      end;
+{$endif GDB}
+
+
+    procedure tprocvardef.write_rtti_data;
+      var
+         pdc : pparaitem;
+         methodkind, paraspec : byte;
+      begin
+        if po_methodpointer in procoptions then
+          begin
+             { write method id and name }
+             rttilist^.concat(new(pai_const,init_8bit(tkmethod)));
+             write_rtti_name;
+
+             { write kind of method (can only be function or procedure)}
+             if rettype.def = pdef(voiddef) then    { ### typecast shoudln't be necessary! (sg) }
+               methodkind := mkProcedure
+             else
+               methodkind := mkFunction;
+             rttilist^.concat(new(pai_const,init_8bit(methodkind)));
+
+             { get # of parameters }
+             rttilist^.concat(new(pai_const,init_8bit(maxparacount)));
+
+             { write parameter info. The parameters must be written in reverse order
+               if this method uses right to left parameter pushing! }
+             if (pocall_leftright in proccalloptions) then
+              pdc:=pparaitem(para^.last)
+             else
+              pdc:=pparaitem(para^.first);
+             while assigned(pdc) do
+               begin
+                 case pdc^.paratyp of
+                   vs_value: paraspec := 0;
+                   vs_const: paraspec := pfConst;
+                   vs_var  : paraspec := pfVar;
+                   vs_out  : paraspec := pfOut;
+                 end;
+                 { write flags for current parameter }
+                 rttilist^.concat(new(pai_const,init_8bit(paraspec)));
+                 { write name of current parameter ### how can I get this??? (sg)}
+                 rttilist^.concat(new(pai_const,init_8bit(0)));
+
+                 { write name of type of current parameter }
+                 pdc^.paratype.def^.write_rtti_name;
+
+                 if (pocall_leftright in proccalloptions) then
+                  pdc:=pparaitem(pdc^.previous)
+                 else
+                  pdc:=pparaitem(pdc^.next);
+               end;
+
+             { write name of result type }
+             rettype.def^.write_rtti_name;
+          end;
+      end;
+
+
+    procedure tprocvardef.write_child_rtti_data;
+      begin
+         {!!!!!!!!}
+      end;
+
+
+    function tprocvardef.is_publishable : boolean;
+      begin
+         is_publishable:=(po_methodpointer in procoptions);
+      end;
+
+    function tprocvardef.gettypename : string;
+      begin
+         if assigned(rettype.def) and
+            (rettype.def<>pdef(voiddef)) then
+           gettypename:='<procedure variable type of function'+demangled_paras+
+             ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
+         else
+           gettypename:='<procedure variable type of procedure'+demangled_paras+
+             ';'+proccalloption2str+'>';
+      end;
+
+
+{***************************************************************************
+                              TOBJECTDEF
+***************************************************************************}
+
+{$ifdef GDB}
+    const
+       vtabletype : word = 0;
+       vtableassigned : boolean = false;
+{$endif GDB}
+
+   constructor tobjectdef.init(odt : tobjectdeftype; const n : string;c : pobjectdef);
+     begin
+        tdef.init;
+        deftype:=objectdef;
+        objecttype:=odt;
+        objectoptions:=[];
+        childof:=nil;
+        symtable:=new(psymtable,init(objectsymtable));
+        symtable^.name := stringdup(n);
+        { create space for vmt !! }
+        vmt_offset:=0;
+        symtable^.datasize:=0;
+        symtable^.defowner:=@self;
+        symtable^.dataalignment:=packrecordalignment[aktpackrecords];
+
+        set_parent(c);
+        objname:=stringdup(n);
+        lastvtableindex:=0;
+
+        { set up guid }
+        isiidguidvalid:=true; { default null guid }
+        fillchar(iidguid,sizeof(iidguid),0); { default null guid }
+        iidstr:=stringdup(''); { default is empty string }
+
+        { set£p implemented interfaces }
+        if objecttype in [odt_class,odt_interfacecorba] then
+          new(implementedinterfaces,init)
+        else
+          implementedinterfaces:=nil;
+
+{$ifdef GDB}
+        writing_stabs:=false;
+        classglobalnb:=0;
+        classptrglobalnb:=0;
+{$endif GDB}
+     end;
+
+
+    constructor tobjectdef.load;
+      var
+         oldread_member : boolean;
+         implintfcount: longint;
+         i: longint;
+      begin
+         tdef.load;
+         deftype:=objectdef;
+         objecttype:=tobjectdeftype(readbyte);
+         savesize:=readlong;
+         vmt_offset:=readlong;
+         objname:=stringdup(readstring);
+         childof:=pobjectdef(readdefref);
+         readsmallset(objectoptions,sizeof(objectoptions));
+         has_rtti:=boolean(readbyte);
+
+         { load guid }
+         iidstr:=nil;
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+              isiidguidvalid:=boolean(readbyte);
+              readguid(iidguid);
+              iidstr:=stringdup(readstring);
+              lastvtableindex:=readlong;
+           end;
+
+         { load implemented interfaces }
+         if objecttype in [odt_class,odt_interfacecorba] then
+           begin
+             new(implementedinterfaces,init);
+             implintfcount:=readlong;
+             for i:=1 to implintfcount do
+               begin
+                  implementedinterfaces^.addintfref(readdefref);
+                  implementedinterfaces^.ioffsets(i)^:=readlong;
+               end;
+           end
+         else
+           implementedinterfaces:=nil;
+
+         oldread_member:=read_member;
+         read_member:=true;
+         symtable:=new(psymtable,loadas(objectsymtable));
+         read_member:=oldread_member;
+
+         symtable^.defowner:=@self;
+         symtable^.name := stringdup(objname^);
+
+         { handles the predefined class tobject  }
+         { the last TOBJECT which is loaded gets }
+         { it !                                  }
+         if (childof=nil) and
+            (objecttype=odt_class) and
+            (upper(objname^)='TOBJECT') then
+           class_tobject:=@self;
+         if (childof=nil) and (objecttype=odt_interfacecom) and
+           (objname^='IUNKNOWN') then
+           interface_iunknown:=@self;
+{$ifdef GDB}
+         writing_stabs:=false;
+         classglobalnb:=0;
+         classptrglobalnb:=0;
+{$endif GDB}
+       end;
+
+
+   destructor tobjectdef.done;
+     begin
+        if assigned(symtable) then
+          dispose(symtable,done);
+        if (oo_is_forward in objectoptions) then
+          Message1(sym_e_class_forward_not_resolved,objname^);
+        stringdispose(objname);
+        stringdispose(iidstr);
+        if assigned(implementedinterfaces) then
+          dispose(implementedinterfaces,done);
+        tdef.done;
+     end;
+
+
+    procedure tobjectdef.write;
+      var
+         oldread_member : boolean;
+         implintfcount : longint;
+         i : longint;
+      begin
+         tdef.write;
+         writebyte(ord(objecttype));
+         writelong(size);
+         writelong(vmt_offset);
+         writestring(objname^);
+         writedefref(childof);
+         writesmallset(objectoptions,sizeof(objectoptions));
+         writebyte(byte(has_rtti));
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+              writebyte(byte(isiidguidvalid));
+              writeguid(iidguid);
+              writestring(iidstr^);
+              writelong(lastvtableindex);
+           end;
+
+         if objecttype in [odt_class,odt_interfacecorba] then
+           begin
+              implintfcount:=implementedinterfaces^.count;
+              writelong(implintfcount);
+              for i:=1 to implintfcount do
+                begin
+                   writedefref(implementedinterfaces^.interfaces(i));
+                   writelong(implementedinterfaces^.ioffsets(i)^);
+                end;
+           end;
+
+         current_ppu^.writeentry(ibobjectdef);
+
+         oldread_member:=read_member;
+         read_member:=true;
+         symtable^.writeas;
+         read_member:=oldread_member;
+      end;
+
+
+    procedure tobjectdef.deref;
+      var
+         oldrecsyms : psymtable;
+      begin
+         inherited deref;
+         resolvedef(pdef(childof));
+         oldrecsyms:=aktrecordsymtable;
+         aktrecordsymtable:=symtable;
+         symtable^.deref;
+         aktrecordsymtable:=oldrecsyms;
+         if objecttype in [odt_class,odt_interfacecorba] then
+           implementedinterfaces^.deref;
+      end;
+
+
+    procedure tobjectdef.set_parent( c : pobjectdef);
+      begin
+        { nothing to do if the parent was not forward !}
+        if assigned(childof) then
+          exit;
+        childof:=c;
+        { some options are inherited !! }
+        if assigned(c) then
+          begin
+             { only important for classes }
+             lastvtableindex:=c^.lastvtableindex;
+             objectoptions:=objectoptions+(c^.objectoptions*
+               [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
+             if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
+               begin
+                  { add the data of the anchestor class }
+                  inc(symtable^.datasize,c^.symtable^.datasize);
+                  if (oo_has_vmt in objectoptions) and
+                     (oo_has_vmt in c^.objectoptions) then
+                    dec(symtable^.datasize,target_os.size_of_pointer);
+                  { if parent has a vmt field then
+                    the offset is the same for the child PM }
+                  if (oo_has_vmt in c^.objectoptions) or is_class(@self) then
+                    begin
+                       vmt_offset:=c^.vmt_offset;
+                       include(objectoptions,oo_has_vmt);
+                    end;
+               end;
+          end;
+        savesize := symtable^.datasize;
+      end;
+
+
+   procedure tobjectdef.insertvmt;
+     begin
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then exit;
+        if (oo_has_vmt in objectoptions) then
+          internalerror(12345)
+        else
+          begin
+             { first round up to multiple of 4 }
+             if (symtable^.dataalignment=2) then
+               begin
+                 if (symtable^.datasize and 1)<>0 then
+                   inc(symtable^.datasize);
+               end
+             else
+              if (symtable^.dataalignment>=4) then
+               begin
+                 if (symtable^.datasize mod 4) <> 0 then
+                   inc(symtable^.datasize,4-(symtable^.datasize mod 4));
+               end;
+             vmt_offset:=symtable^.datasize;
+             inc(symtable^.datasize,target_os.size_of_pointer);
+             include(objectoptions,oo_has_vmt);
+          end;
+     end;
+
+
+   procedure tobjectdef.check_forwards;
+     begin
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then exit; { Kaz: ??? }
+        symtable^.check_forwards;
+        if (oo_is_forward in objectoptions) then
+          begin
+             { ok, in future, the forward can be resolved }
+             Message1(sym_e_class_forward_not_resolved,objname^);
+             exclude(objectoptions,oo_is_forward);
+          end;
+     end;
+
+
+   { true, if self inherits from d (or if they are equal) }
+   function tobjectdef.is_related(d : pobjectdef) : boolean;
+     var
+        hp : pobjectdef;
+     begin
+        hp:=@self;
+        while assigned(hp) do
+          begin
+             if hp=d then
+               begin
+                  is_related:=true;
+                  exit;
+               end;
+             hp:=hp^.childof;
+          end;
+        is_related:=false;
+     end;
+
+   var
+      sd : pprocdef;
+
+   procedure _searchdestructor(sym : pnamedindexobject);
+
+     var
+        p : pprocdef;
+
+     begin
+        { if we found already a destructor, then we exit }
+        if assigned(sd) then
+          exit;
+        if psym(sym)^.typ=procsym then
+          begin
+             p:=pprocsym(sym)^.definition;
+             while assigned(p) do
+               begin
+                  if p^.proctypeoption=potype_destructor then
+                    begin
+                       sd:=p;
+                       exit;
+                    end;
+                  p:=p^.nextoverloaded;
+               end;
+          end;
+     end;
+
+   function tobjectdef.searchdestructor : pprocdef;
+
+     var
+        o : pobjectdef;
+
+     begin
+        searchdestructor:=nil;
+        o:=@self;
+        sd:=nil;
+        while assigned(o) do
+          begin
+             symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
+             if assigned(sd) then
+               begin
+                  searchdestructor:=sd;
+                  exit;
+               end;
+             o:=o^.childof;
+          end;
+     end;
+
+    function tobjectdef.size : longint;
+      begin
+        if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
+          size:=target_os.size_of_pointer
+        else
+          size:=symtable^.datasize;
+      end;
+
+
+    function tobjectdef.alignment:longint;
+      begin
+        alignment:=symtable^.dataalignment;
+      end;
+
+
+    function tobjectdef.vmtmethodoffset(index:longint):longint;
+      begin
+        { for offset of methods for classes, see rtl/inc/objpash.inc }
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then
+          vmtmethodoffset:=index*target_os.size_of_pointer
+        else if (objecttype=odt_class) then
+           vmtmethodoffset:=(index+12)*target_os.size_of_pointer
+        else
+{$ifdef WITHDMT}
+         vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
+{$else WITHDMT}
+         vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
+{$endif WITHDMT}
+      end;
+
+
+    function tobjectdef.vmt_mangledname : string;
+    {DM: I get a nil pointer on the owner name. I don't know if this
+     may happen, and I have therefore fixed the problem by doing nil pointer
+     checks.}
+    var
+      s1,s2:string;
+    begin
+        if not(oo_has_vmt in objectoptions) then
+          Message1(parser_object_has_no_vmt,objname^);
+        if owner^.name=nil then
+          s1:=''
+        else
+          s1:=owner^.name^;
+        if objname=nil then
+          s2:=''
+        else
+          s2:=Upper(objname^);
+        vmt_mangledname:='VMT_'+s1+'$_'+s2;
+    end;
+
+
+    function tobjectdef.rtti_name : string;
+    var
+      s1,s2:string;
+    begin
+       if owner^.name=nil then
+         s1:=''
+       else
+         s1:=owner^.name^;
+       if objname=nil then
+         s2:=''
+       else
+         s2:=Upper(objname^);
+       rtti_name:='RTTI_'+s1+'$_'+s2;
+    end;
+
+
+{$ifdef GDB}
+    procedure addprocname(p :pnamedindexobject);
+    var virtualind,argnames : string;
+        news, newrec : pchar;
+        pd,ipd : pprocdef;
+        lindex : longint;
+        para : pparaitem;
+        arglength : byte;
+        sp : char;
+
+    begin
+      If psym(p)^.typ = procsym then
+       begin
+                pd := pprocsym(p)^.definition;
+                { this will be used for full implementation of object stabs
+                not yet done }
+                ipd := pd;
+                while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
+                if (po_virtualmethod in pd^.procoptions) then
+                  begin
+                    lindex := pd^.extnumber;
+                    {doesnt seem to be necessary
+                    lindex := lindex or $80000000;}
+                    virtualind := '*'+tostr(lindex)+';'+ipd^._class^.classnumberstring+';'
+                  end
+                 else
+                  virtualind := '.';
+
+                 { used by gdbpas to recognize constructor and destructors }
+                 if (pd^.proctypeoption=potype_constructor) then
+                   argnames:='__ct__'
+                 else if (pd^.proctypeoption=potype_destructor) then
+                   argnames:='__dt__'
+                 else
+                   argnames := '';
+
+                { arguments are not listed here }
+                {we don't need another definition}
+                 para := pparaitem(pd^.para^.first);
+                 while assigned(para) do
+                   begin
+                   if para^.paratype.def^.deftype = formaldef then
+                     begin
+                        if para^.paratyp=vs_out then
+                          argnames := argnames+'3out'
+                        else if para^.paratyp=vs_var then
+                          argnames := argnames+'3var'
+                        else if para^.paratyp=vs_const then
+                          argnames:=argnames+'5const'
+                        else if para^.paratyp=vs_out then
+                          argnames:=argnames+'3out';
+                     end
+                   else
+                     begin
+                     { if the arg definition is like (v: ^byte;..
+                     there is no sym attached to data !!! }
+                     if assigned(para^.paratype.def^.typesym) then
+                       begin
+                          arglength := length(para^.paratype.def^.typesym^.name);
+                          argnames := argnames + tostr(arglength)+para^.paratype.def^.typesym^.name;
+                       end
+                     else
+                       begin
+                          argnames:=argnames+'11unnamedtype';
+                       end;
+                     end;
+                   para := pparaitem(para^.next);
+                   end;
+                ipd^.is_def_stab_written := written;
+                { here 2A must be changed for private and protected }
+                { 0 is private 1 protected and 2 public }
+                if (sp_private in psym(p)^.symoptions) then sp:='0'
+                else if (sp_protected in psym(p)^.symoptions) then sp:='1'
+                else sp:='2';
+                newrec := strpnew(p^.name+'::'+ipd^.numberstring
+                     +'=##'+pd^.rettype.def^.numberstring+';:'+argnames+';'+sp+'A'
+                     +virtualind+';');
+               { get spare place for a string at the end }
+               if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
+                 begin
+                    getmem(news,stabrecsize+memsizeinc);
+                    strcopy(news,stabrecstring);
+                    freemem(stabrecstring,stabrecsize);
+                    stabrecsize:=stabrecsize+memsizeinc;
+                    stabrecstring:=news;
+                 end;
+               strcat(StabRecstring,newrec);
+               {freemem(newrec,memsizeinc);    }
+               strdispose(newrec);
+               {This should be used for case !!}
+               RecOffset := RecOffset + pd^.size;
+       end;
+    end;
+
+
+    function tobjectdef.stabstring : pchar;
+      var anc : pobjectdef;
+          oldrec : pchar;
+          storenb, oldrecsize : longint;
+          str_end : string;
+      begin
+        if not (is_class(@self)) or writing_stabs then
+          begin
+            storenb:=globalnb;
+            globalnb:=classptrglobalnb;
+            oldrec := stabrecstring;
+            oldrecsize:=stabrecsize;
+            stabrecsize:=memsizeinc;
+            GetMem(stabrecstring,stabrecsize);
+            strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
+            if assigned(childof) then
+              begin
+                {only one ancestor not virtual, public, at base offset 0 }
+                {       !1           ,    0       2         0    ,       }
+                strpcopy(strend(stabrecstring),'!1,020,'+childof^.classnumberstring+';');
+              end;
+            {virtual table to implement yet}
+            RecOffset := 0;
+            symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
+            if (oo_has_vmt in objectoptions) then
+              if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
+                 begin
+                    strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
+                      +','+tostr(vmt_offset*8)+';');
+                 end;
+            symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
+            if (oo_has_vmt in objectoptions) then
+              begin
+                 anc := @self;
+                 while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
+                   anc := anc^.childof;
+                 { just in case anc = self }
+                 str_end:=';~%'+anc^.classnumberstring+';';
+              end
+            else
+              str_end:=';';
+            strpcopy(strend(stabrecstring),str_end);
+            stabstring := strnew(StabRecString);
+            freemem(stabrecstring,stabrecsize);
+            stabrecstring := oldrec;
+            stabrecsize:=oldrecsize;
+            globalnb:=storenb;
+          end
+        else
+          begin
+            stabstring:=strpnew('*'+classnumberstring);
+          end;
+      end;
+
+   procedure tobjectdef.set_globalnb;
+     begin
+         classglobalnb:=PGlobalTypeCount^;
+         globalnb:=classglobalnb;
+         inc(PglobalTypeCount^);
+         { classes need two type numbers, the globalnb is set to the ptr }
+         if objecttype=odt_class then
+           begin
+             classptrglobalnb:=PGlobalTypeCount^;
+             globalnb:=classptrglobalnb;
+             inc(PglobalTypeCount^);
+           end;
+     end;
+
+   function tobjectdef.classnumberstring : string;
+     var
+       onb : word;
+     begin
+       if globalnb=0 then
+         numberstring;
+       if objecttype=odt_class then
+         begin
+           onb:=globalnb;
+           globalnb:=classglobalnb;
+           classnumberstring:=numberstring;
+           globalnb:=onb;
+         end
+       else
+         classnumberstring:=numberstring;
+     end;
+
+   function tobjectdef.classptrnumberstring : string;
+     var
+       onb : word;
+     begin
+       if globalnb=0 then
+         numberstring;
+       if objecttype=odt_class then
+         begin
+           onb:=globalnb;
+           globalnb:=classptrglobalnb;
+           classptrnumberstring:=numberstring;
+           globalnb:=onb;
+         end
+       else
+         classptrnumberstring:=numberstring;
+     end;
+
+    procedure tobjectdef.concatstabto(asmlist : paasmoutput);
+      var st : pstring;
+      begin
+        if not(objecttype=odt_class) then
+          begin
+            inherited concatstabto(asmlist);
+            exit;
+          end;
+
+      if ((typesym=nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
+         (is_def_stab_written = not_written) then
+        begin
+          if globalnb=0 then
+            set_globalnb;
+          { Write the record class itself }
+          writing_stabs:=true;
+          if assigned(typesym) then
+            begin
+              st:=typesym^._name;
+              typesym^._name:=stringdup(' ');
+            end;
+          globalnb:=classglobalnb;
+          inherited concatstabto(asmlist);
+          if assigned(typesym) then
+            begin
+              stringdispose(typesym^._name);
+              typesym^._name:=st;
+            end;
+          globalnb:=classptrglobalnb;
+          writing_stabs:=false;
+          { Write the invisible pointer class }
+          is_def_stab_written:=not_written;
+          inherited concatstabto(asmlist);
+        end;
+      end;
+{$endif GDB}
+
+
+    procedure tobjectdef.write_child_init_data;
+      begin
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
+      end;
+
+
+    procedure tobjectdef.write_init_data;
+      begin
+         case objecttype of
+            odt_class:
+              rttilist^.concat(new(pai_const,init_8bit(tkclass)));
+            odt_object:
+              rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+            odt_interfacecom:
+              rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
+            odt_interfacecorba:
+              rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
+          else
+            exit;
+          end;
+
+         { generate the name }
+         rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
+         rttilist^.concat(new(pai_string,init(objname^)));
+
+         rttilist^.concat(new(pai_const,init_32bit(size)));
+         count:=0;
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+           end
+         else
+           begin
+              symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
+              rttilist^.concat(new(pai_const,init_32bit(count)));
+              symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
+           end;
+      end;
+
+
+    function tobjectdef.needs_inittable : boolean;
+      var
+         oldb : boolean;
+      begin
+         case objecttype of
+            odt_interfacecom: needs_inittable:=true;
+            odt_object:
+              begin
+                 { there are recursive calls to needs_inittable possible, }
+                 { so we have to change to old value how else should      }
+                 { we do that ? check_rec_rtti can't be a nested          }
+                 { procedure of needs_rtti !                              }
+                 oldb:=binittable;
+                 binittable:=false;
+                 symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
+                 needs_inittable:=binittable;
+                 binittable:=oldb;
+              end;
+            else needs_inittable:=false;
+         end;
+      end;
+
+
+    procedure count_published_properties(sym:pnamedindexobject);
+      begin
+         if needs_prop_entry(psym(sym)) and
+          (psym(sym)^.typ<>varsym) then
+           inc(count);
+      end;
+
+
+    procedure write_property_info(sym : pnamedindexobject);
+      var
+         proctypesinfo : byte;
+
+      procedure writeproc(proc : psymlist; shiftvalue : byte);
+
+        var
+           typvalue : byte;
+           hp : psymlistitem;
+           address : longint;
+
+        begin
+           if not(assigned(proc) and assigned(proc^.firstsym))  then
+             begin
+                rttilist^.concat(new(pai_const,init_32bit(1)));
+                typvalue:=3;
+             end
+           else if proc^.firstsym^.sym^.typ=varsym then
+             begin
+                address:=0;
+                hp:=proc^.firstsym;
+                while assigned(hp) do
+                  begin
+                     inc(address,pvarsym(hp^.sym)^.address);
+                     hp:=hp^.next;
+                  end;
+                rttilist^.concat(new(pai_const,init_32bit(address)));
+                typvalue:=0;
+             end
+           else
+             begin
+                if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
+                  begin
+                     rttilist^.concat(new(pai_const_symbol,initname(pprocdef(proc^.def)^.mangledname)));
+                     typvalue:=1;
+                  end
+                else
+                  begin
+                     { virtual method, write vmt offset }
+                     rttilist^.concat(new(pai_const,init_32bit(
+                       pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber))));
+                     typvalue:=2;
+                  end;
+             end;
+           proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
+        end;
+
+      begin
+         if needs_prop_entry(psym(sym)) then
+           case psym(sym)^.typ of
+              varsym:
+                begin
+{$ifdef dummy}
+                   if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
+                     not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
+                     internalerror(1509992);
+                   { access to implicit class property as field }
+                   proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
+                   rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
+                   rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
+                   rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
+                   { per default stored }
+                   rttilist^.concat(new(pai_const,init_32bit(1)));
+                   { index as well as ... }
+                   rttilist^.concat(new(pai_const,init_32bit(0)));
+                   { default value are zero }
+                   rttilist^.concat(new(pai_const,init_32bit(0)));
+                   rttilist^.concat(new(pai_const,init_16bit(count)));
+                   inc(count);
+                   rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
+                   rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.realname))));
+                   rttilist^.concat(new(pai_string,init(pvarsym(sym)^.realname)));
+{$endif dummy}
+                end;
+              propertysym:
+                begin
+                   if ppo_indexed in ppropertysym(sym)^.propoptions then
+                     proctypesinfo:=$40
+                   else
+                     proctypesinfo:=0;
+                   rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype.def^.get_rtti_label)));
+                   writeproc(ppropertysym(sym)^.readaccess,0);
+                   writeproc(ppropertysym(sym)^.writeaccess,2);
+                   { isn't it stored ? }
+                   if not(ppo_stored in ppropertysym(sym)^.propoptions) then
+                     begin
+                        rttilist^.concat(new(pai_const,init_32bit(0)));
+                        proctypesinfo:=proctypesinfo or (3 shl 4);
+                     end
+                   else
+                     writeproc(ppropertysym(sym)^.storedaccess,4);
+                   rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
+                   rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
+                   rttilist^.concat(new(pai_const,init_16bit(count)));
+                   inc(count);
+                   rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
+                   rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.realname))));
+                   rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.realname)));
+                end;
+              else internalerror(1509992);
+           end;
+      end;
+
+
+    procedure generate_published_child_rtti(sym : pnamedindexobject);
+      begin
+         if needs_prop_entry(psym(sym)) then
+           case psym(sym)^.typ of
+              varsym:
+                ;
+                { now ignored:
+                ;
+                { now ignored
+                pvarsym(sym)^.vartype.def^.get_rtti_label;
+                }
+                }
+              propertysym:
+                ppropertysym(sym)^.proptype.def^.get_rtti_label;
+              else
+                internalerror(1509991);
+           end;
+      end;
+
+
+    procedure tobjectdef.write_child_rtti_data;
+      begin
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
+      end;
+
+
+    procedure tobjectdef.generate_rtti;
+      begin
+         if not has_rtti then
+          begin
+            has_rtti:=true;
+            getdatalabel(rtti_label);
+            write_child_rtti_data;
+            rttilist^.concat(new(pai_symbol,initname_global(rtti_name,0)));
+            rttilist^.concat(new(pai_label,init(rtti_label)));
+            write_rtti_data;
+            rttilist^.concat(new(pai_symbol_end,initname(rtti_name)));
+          end;
+      end;
+
+    type
+       tclasslistitem = object(tlinkedlist_item)
+          index : longint;
+          p : pobjectdef;
+       end;
+       pclasslistitem = ^tclasslistitem;
+
+    var
+       classtablelist : tlinkedlist;
+       tablecount : longint;
+
+    function searchclasstablelist(p : pobjectdef) : pclasslistitem;
+
+      var
+         hp : pclasslistitem;
+
+      begin
+         hp:=pclasslistitem(classtablelist.first);
+         while assigned(hp) do
+           if hp^.p=p then
+             begin
+                searchclasstablelist:=hp;
+                exit;
+             end
+           else
+             hp:=pclasslistitem(hp^.next);
+         searchclasstablelist:=nil;
+      end;
+
+    procedure count_published_fields(sym:pnamedindexobject);
+      var
+         hp : pclasslistitem;
+      begin
+         if needs_prop_entry(psym(sym)) and
+          (psym(sym)^.typ=varsym) then
+          begin
+             if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
+               internalerror(0206001);
+             hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
+             if not(assigned(hp)) then
+               begin
+                  hp:=new(pclasslistitem,init);
+                  hp^.p:=pobjectdef(pvarsym(sym)^.vartype.def);
+                  hp^.index:=tablecount;
+                  classtablelist.concat(hp);
+                  inc(tablecount);
+               end;
+             inc(count);
+          end;
+      end;
+
+    procedure writefields(sym:pnamedindexobject);
+      var
+         hp : pclasslistitem;
+      begin
+         if needs_prop_entry(psym(sym)) and
+          (psym(sym)^.typ=varsym) then
+          begin
+             rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
+             hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
+             if not(assigned(hp)) then
+               internalerror(0206002);
+             rttilist^.concat(new(pai_const,init_16bit(hp^.index)));
+             rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.realname))));
+             rttilist^.concat(new(pai_string,init(pvarsym(sym)^.realname)));
+          end;
+      end;
+
+    function tobjectdef.generate_field_table : pasmlabel;
+
+      var
+         fieldtable,
+         classtable : pasmlabel;
+         hp : pclasslistitem;
+
+      begin
+         classtablelist.init;
+         getdatalabel(fieldtable);
+         getdatalabel(classtable);
+         count:=0;
+         tablecount:=0;
+         symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
+         rttilist^.concat(new(pai_label,init(fieldtable)));
+         rttilist^.concat(new(pai_const,init_16bit(count)));
+         rttilist^.concat(new(pai_const_symbol,init(classtable)));
+         symtable^.foreach({$ifdef FPC}@{$endif}writefields);
+
+         { generate the class table }
+         rttilist^.concat(new(pai_label,init(classtable)));
+         rttilist^.concat(new(pai_const,init_16bit(tablecount)));
+         hp:=pclasslistitem(classtablelist.first);
+         while assigned(hp) do
+           begin
+              rttilist^.concat(new(pai_const_symbol,initname(pobjectdef(hp^.p)^.vmt_mangledname)));
+              hp:=pclasslistitem(hp^.next);
+           end;
+
+         generate_field_table:=fieldtable;
+         classtablelist.done;
+      end;
+
+    function tobjectdef.next_free_name_index : longint;
+      var
+         i : longint;
+      begin
+         if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
+           i:=childof^.next_free_name_index
+         else
+           i:=0;
+         count:=0;
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+         next_free_name_index:=i+count;
+      end;
+
+
+    procedure tobjectdef.write_rtti_data;
+      begin
+         case objecttype of
+           odt_class: rttilist^.concat(new(pai_const,init_8bit(tkclass)));
+           odt_object: rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+           odt_interfacecom: rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
+           odt_interfacecorba: rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
+         else
+           exit;
+         end;
+
+         { generate the name }
+         rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
+         rttilist^.concat(new(pai_string,init(objname^)));
+
+         { write class type }
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           rttilist^.concat(new(pai_const,init_32bit(0)))
+         else
+           rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
+
+         { write owner typeinfo }
+         if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
+           rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
+         else
+           rttilist^.concat(new(pai_const,init_32bit(0)));
+
+         { count total number of properties }
+         if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
+           count:=childof^.next_free_name_index
+         else
+           count:=0;
+
+         { write it }
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+         rttilist^.concat(new(pai_const,init_16bit(count)));
+
+         { write unit name }
+         rttilist^.concat(new(pai_const,init_8bit(length(current_module^.realmodulename^))));
+         rttilist^.concat(new(pai_string,init(current_module^.realmodulename^)));
+
+         { write published properties count }
+         count:=0;
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
+         rttilist^.concat(new(pai_const,init_16bit(count)));
+
+         { count is used to write nameindex   }
+
+         { but we need an offset of the owner }
+         { to give each property an own slot  }
+         if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
+           count:=childof^.next_free_name_index
+         else
+           count:=0;
+
+         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
+      end;
+
+
+    function tobjectdef.is_publishable : boolean;
+      begin
+         is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
+      end;
+
+    function  tobjectdef.get_rtti_label : string;
+
+      begin
+         generate_rtti;
+         get_rtti_label:=rtti_name;
+      end;
+
+{****************************************************************************
+                                TFORWARDDEF
+****************************************************************************}
+
+   constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
+     var
+       oldregisterdef : boolean;
+     begin
+        { never register the forwarddefs, they are disposed at the
+          end of the type declaration block }
+        oldregisterdef:=registerdef;
+        registerdef:=false;
+        inherited init;
+        registerdef:=oldregisterdef;
+        deftype:=forwarddef;
+        tosymname:=s;
+        forwardpos:=pos;
+     end;
+
+
+    function tforwarddef.gettypename:string;
+      begin
+        gettypename:='unresolved forward to '+tosymname;
+      end;
+
+
+{****************************************************************************
+                             TIMPLEMENTEDINTERFACES
+****************************************************************************}
+    type
+      pnamemap = ^tnamemap;
+      tnamemap = object(tnamedindexobject)
+        newname: pstring;
+        constructor init(const aname, anewname: string);
+        destructor  done; virtual;
+      end;
+
+    constructor tnamemap.init(const aname, anewname: string);
+      begin
+        inherited initname(name);
+        newname:=stringdup(anewname);
+      end;
+
+    destructor  tnamemap.done;
+      begin
+        stringdispose(newname);
+        inherited done;
+      end;
+
+
+    type
+      pprocdefstore = ^tprocdefstore;
+      tprocdefstore = object(tnamedindexobject)
+        procdef: pprocdef;
+        constructor init(aprocdef: pprocdef);
+      end;
+
+    constructor tprocdefstore.init(aprocdef: pprocdef);
+      begin
+        inherited init;
+        procdef:=aprocdef;
+      end;
+
+
+    type
+      pimplintfentry = ^timplintfentry;
+      timplintfentry = object(tnamedindexobject)
+        intf: pobjectdef;
+        ioffs: longint;
+        namemappings: pdictionary;
+        procdefs: pindexarray;
+        constructor init(aintf: pobjectdef);
+        destructor  done; virtual;
+      end;
+
+    constructor timplintfentry.init(aintf: pobjectdef);
+      begin
+        inherited init;
+        intf:=aintf;
+        ioffs:=-1;
+        namemappings:=nil;
+        procdefs:=nil;
+      end;
+
+    destructor  timplintfentry.done;
+      begin
+        if assigned(namemappings) then
+          dispose(namemappings,done);
+        if assigned(procdefs) then
+          dispose(procdefs,done);
+        inherited done;
+      end;
+
+
+    constructor timplementedinterfaces.init;
+      begin
+        finterfaces.init(1);
+      end;
+
+    destructor  timplementedinterfaces.done;
+      begin
+        finterfaces.done;
+      end;
+
+    function  timplementedinterfaces.count: longint;
+      begin
+        count:=finterfaces.count;
+      end;
+
+    procedure timplementedinterfaces.checkindex(intfindex: longint);
+      begin
+        if (intfindex<1) or (intfindex>count) then
+          InternalError(200006123);
+      end;
+
+    function  timplementedinterfaces.interfaces(intfindex: longint): pobjectdef;
+      begin
+        checkindex(intfindex);
+        interfaces:=pimplintfentry(finterfaces.search(intfindex))^.intf;
+      end;
+
+    function  timplementedinterfaces.ioffsets(intfindex: longint): plongint;
+      begin
+        checkindex(intfindex);
+        ioffsets:=@pimplintfentry(finterfaces.search(intfindex))^.ioffs;
+      end;
+
+    function  timplementedinterfaces.searchintf(def: pdef): longint;
+      var
+        i: longint;
+      begin
+        i:=1;
+        while (i<=count) and (pdef(interfaces(i))<>def) do inc(i);
+        if i<=count then
+          searchintf:=i
+        else
+          searchintf:=-1;
+      end;
+
+    procedure timplementedinterfaces.deref;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            resolvedef(pdef(intf));
+      end;
+
+    procedure timplementedinterfaces.addintfref(def: pdef);
+      begin
+        finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
+      end;
+
+    procedure timplementedinterfaces.addintf(def: pdef);
+      begin
+        if not assigned(def) or (searchintf(def)<>-1) or (def^.deftype<>objectdef) or
+           not (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]) then
+          internalerror(200006124);
+        finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
+      end;
+
+    procedure timplementedinterfaces.clearmappings;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            begin
+             if assigned(namemappings) then
+               dispose(namemappings,done);
+             namemappings:=nil;
+            end;
+      end;
+
+    procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          begin
+            if not assigned(namemappings) then
+              new(namemappings,init);
+            namemappings^.insert(new(pnamemap,init(name,newname)));
+          end;
+      end;
+
+    function  timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
+      begin
+        checkindex(intfindex);
+        if not assigned(nextexist) then
+          with pimplintfentry(finterfaces.search(intfindex))^ do
+            begin
+              if assigned(namemappings) then
+                nextexist:=namemappings^.search(name)
+              else
+                nextexist:=nil;
+            end;
+        if assigned(nextexist) then
+          begin
+            getmappings:=pnamemap(nextexist)^.newname^;
+            nextexist:=pnamemap(nextexist)^.listnext;
+          end
+        else
+          getmappings:='';
+      end;
+
+    procedure timplementedinterfaces.clearimplprocs;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            begin
+              if assigned(procdefs) then
+                dispose(procdefs,done);
+              procdefs:=nil;
+            end;
+      end;
+
+    procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: pprocdef);
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          begin
+            if not assigned(procdefs) then
+              new(procdefs,init(4));
+            procdefs^.insert(new(pprocdefstore,init(procdef)));
+          end;
+      end;
+
+    function  timplementedinterfaces.implproccount(intfindex: longint): longint;
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          if assigned(procdefs) then
+            implproccount:=procdefs^.count
+          else
+            implproccount:=0;
+      end;
+
+    function  timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): pprocdef;
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          if assigned(procdefs) then
+            implprocs:=pprocdefstore(procdefs^.search(procindex))^.procdef
+          else
+            internalerror(200006131);
+      end;
+
+    function  timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
+      var
+        possible: boolean;
+        i: longint;
+        iiep1: pindexarray;
+        iiep2: pindexarray;
+      begin
+        checkindex(intfindex);
+        checkindex(remainindex);
+        iiep1:=pimplintfentry(finterfaces.search(intfindex))^.procdefs;
+        iiep2:=pimplintfentry(finterfaces.search(remainindex))^.procdefs;
+        if not assigned(iiep1) then { empty interface is mergeable :-) }
+          begin
+            possible:=true;
+            weight:=0;
+          end
+        else
+          begin
+            possible:=assigned(iiep2) and (iiep1^.count<=iiep2^.count);
+            i:=1;
+            while (possible) and (i<=iiep1^.count) do
+              begin
+                possible:=
+                  pprocdefstore(iiep1^.search(i))^.procdef=
+                  pprocdefstore(iiep2^.search(i))^.procdef;
+                inc(i);
+              end;
+            if possible then
+              weight:=iiep1^.count;
+          end;
+        isimplmergepossible:=possible;
+      end;
+
+{****************************************************************************
+                                  TERRORDEF
+****************************************************************************}
+
+   constructor terrordef.init;
+     begin
+        inherited init;
+        deftype:=errordef;
+     end;
+
+
+{$ifdef GDB}
+    function terrordef.stabstring : pchar;
+      begin
+         stabstring:=strpnew('error'+numberstring);
+      end;
+{$endif GDB}
+
+    function terrordef.gettypename:string;
+
+      begin
+         gettypename:='<erroneous type>';
+      end;
+
+{
+  $Log$
+  Revision 1.26  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.25  2000/10/31 22:02:52  peter
+    * symtable splitted, no real code changes
+
+  Revision 1.24  2000/10/21 18:16:12  florian
+    * a lot of changes:
+       - basic dyn. array support
+       - basic C++ support
+       - some work for interfaces done
+       ....
+
+  Revision 1.23  2000/10/15 07:47:52  peter
+    * unit names and procedure names are stored mixed case
+
+  Revision 1.22  2000/10/14 10:14:52  peter
+    * moehrendorf oct 2000 rewrite
+
+  Revision 1.21  2000/10/04 23:16:48  pierre
+   * object stabs fix (merged)
+
+  Revision 1.20  2000/10/01 19:48:25  peter
+    * lot of compile updates for cg11
+
+  Revision 1.19  2000/09/24 21:19:52  peter
+    * delphi compile fixes
+
+  Revision 1.18  2000/09/24 15:06:28  peter
+    * use defines.inc
+
+  Revision 1.17  2000/09/19 23:08:02  pierre
+   * fixes for local class debuggging problem (merged)
+
+  Revision 1.16  2000/09/10 20:13:37  peter
+    * fixed array of const writing instead of array of tvarrec (merged)
+
+  Revision 1.15  2000/09/09 18:36:40  peter
+    * fixed C alignment of array of record (merged)
+
+  Revision 1.14  2000/08/27 20:19:39  peter
+    * store strings with case in ppu, when an internal symbol is created
+      a '$' is prefixed so it's not automatic uppercased
+
+  Revision 1.13  2000/08/27 16:11:53  peter
+    * moved some util functions from globals,cobjects to cutils
+    * splitted files into finput,fmodule
+
+  Revision 1.12  2000/08/21 11:27:44  pierre
+   * fix the stabs problems
+
+  Revision 1.11  2000/08/16 18:33:54  peter
+    * splitted namedobjectitem.next into indexnext and listnext so it
+      can be used in both lists
+    * don't allow "word = word" type definitions (merged)
+
+  Revision 1.10  2000/08/16 13:06:06  florian
+    + support of 64 bit integer constants
+
+  Revision 1.9  2000/08/13 13:06:37  peter
+    * store parast always for procdef (browser needs still update)
+    * add default parameter value to demangledpara
+
+  Revision 1.8  2000/08/08 19:28:57  peter
+    * memdebug/memory patches (merged)
+    * only once illegal directive (merged)
+
+  Revision 1.7  2000/08/06 19:39:28  peter
+    * default parameters working !
+
+  Revision 1.6  2000/08/06 14:17:15  peter
+    * overload fixes (merged)
+
+  Revision 1.5  2000/08/03 13:17:26  jonas
+    + allow regvars to be used inside inlined procs, which required  the
+      following changes:
+        + load regvars in genentrycode/free them in genexitcode (cgai386)
+        * moved all regvar related code to new regvars unit
+        + added pregvarinfo type to hcodegen
+        + added regvarinfo field to tprocinfo (symdef/symdefh)
+        * deallocate the regvars of the caller in secondprocinline before
+          inlining the called procedure and reallocate them afterwards
+
+  Revision 1.4  2000/08/02 19:49:59  peter
+    * first things for default parameters
+
+  Revision 1.3  2000/07/13 12:08:27  michael
+  + patched to 1.1.0 with former 1.09patch from peter
+
+  Revision 1.2  2000/07/13 11:32:49  michael
+  + removed logs
+
+}

+ 521 - 79
compiler/symdef.pas

@@ -197,6 +197,8 @@ interface
 
 
        pprocdef = ^tprocdef;
        pprocdef = ^tprocdef;
 
 
+       pimplementedinterfaces = ^timplementedinterfaces;
+
        pobjectdef = ^tobjectdef;
        pobjectdef = ^tobjectdef;
        tobjectdef = object(tstoreddef)
        tobjectdef = object(tstoreddef)
           childof  : pobjectdef;
           childof  : pobjectdef;
@@ -211,7 +213,14 @@ interface
           classptrglobalnb : word;
           classptrglobalnb : word;
           writing_stabs : boolean;
           writing_stabs : boolean;
 {$endif GDB}
 {$endif GDB}
-          constructor init(const n : string;c : pobjectdef);
+          objecttype : tobjectdeftype;
+          isiidguidvalid: boolean;
+          iidguid: TGUID;
+          iidstr: pstring;
+          lastvtableindex: longint;
+          { store implemented interfaces defs and name mappings }
+          implementedinterfaces: pimplementedinterfaces;
+          constructor init(ot : tobjectdeftype;const n : string;c : pobjectdef);
           constructor load;
           constructor load;
           destructor  done;virtual;
           destructor  done;virtual;
           procedure write;virtual;
           procedure write;virtual;
@@ -225,10 +234,6 @@ interface
           function  rtti_name : string;
           function  rtti_name : string;
           procedure check_forwards;
           procedure check_forwards;
           function  is_related(d : pobjectdef) : boolean;
           function  is_related(d : pobjectdef) : boolean;
-          function  is_class : boolean;
-          function  is_interface : boolean;
-          function  is_cppclass : boolean;
-          function  is_object : boolean;
           function  next_free_name_index : longint;
           function  next_free_name_index : longint;
           procedure insertvmt;
           procedure insertvmt;
           procedure set_parent(c : pobjectdef);
           procedure set_parent(c : pobjectdef);
@@ -253,6 +258,35 @@ interface
           function generate_field_table : pasmlabel;
           function generate_field_table : pasmlabel;
        end;
        end;
 
 
+       timplementedinterfaces = object
+         constructor init;
+         destructor  done; virtual;
+
+         function  count: longint;
+         function  interfaces(intfindex: longint): pobjectdef;
+         function  ioffsets(intfindex: longint): plongint;
+         function  searchintf(def: pdef): longint;
+         procedure addintf(def: pdef);
+
+         procedure deref;
+         procedure addintfref(def: pdef);
+
+         procedure clearmappings;
+         procedure addmappings(intfindex: longint; const name, newname: string);
+         function  getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
+
+         procedure clearimplprocs;
+         procedure addimplproc(intfindex: longint; procdef: pprocdef);
+         function  implproccount(intfindex: longint): longint;
+         function  implprocs(intfindex: longint; procindex: longint): pprocdef;
+         function  isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
+
+       private
+         finterfaces: tindexarray;
+         procedure checkindex(intfindex: longint);
+       end;
+
+
        pclassrefdef = ^tclassrefdef;
        pclassrefdef = ^tclassrefdef;
        tclassrefdef = object(tpointerdef)
        tclassrefdef = object(tpointerdef)
           constructor init(def : pdef);
           constructor init(def : pdef);
@@ -617,6 +651,9 @@ interface
                                   { used for stabs }
                                   { used for stabs }
 
 
        class_tobject : pobjectdef;   { pointer to the anchestor of all classes }
        class_tobject : pobjectdef;   { pointer to the anchestor of all classes }
+       interface_iunknown : pobjectdef; { KAZ: pointer to the ancestor }
+       rec_tguid : precorddef;          { KAZ: pointer to the TGUID type }
+                                        { of all interfaces            }
        pvmtdef       : ppointerdef;  { type of classrefs }
        pvmtdef       : ppointerdef;  { type of classrefs }
 
 
     const
     const
@@ -638,6 +675,15 @@ interface
     function typeglobalnumber(const s : string) : string;
     function typeglobalnumber(const s : string) : string;
 {$endif GDB}
 {$endif GDB}
 
 
+    { should be in the types unit, but the types unit uses the node stuff :( }
+    function is_interfacecom(def: pdef): boolean;
+    function is_interfacecorba(def: pdef): boolean;
+    function is_interface(def: pdef): boolean;
+    function is_class(def: pdef): boolean;
+    function is_object(def: pdef): boolean;
+    function is_cppclass(def: pdef): boolean;
+    function is_class_or_interface(def: pdef): boolean;
+
     procedure reset_global_defs;
     procedure reset_global_defs;
 
 
 
 
@@ -2739,8 +2785,8 @@ implementation
             (psym(s)^.typ=varsym) and
             (psym(s)^.typ=varsym) and
             assigned(pvarsym(s)^.vartype.def) then
             assigned(pvarsym(s)^.vartype.def) then
           begin
           begin
-            if ((pvarsym(s)^.vartype.def^.deftype<>objectdef) or
-               not(pobjectdef(pvarsym(s)^.vartype.def)^.is_class)) then
+            if (pvarsym(s)^.vartype.def^.deftype<>objectdef) or
+               not(is_class(pdef(pvarsym(s)^.vartype.def))) then
              binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
              binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
           end;
           end;
       end;
       end;
@@ -2912,8 +2958,8 @@ implementation
       begin
       begin
          if ((psym(sym)^.typ=varsym) and
          if ((psym(sym)^.typ=varsym) and
             pvarsym(sym)^.vartype.def^.needs_inittable)
             pvarsym(sym)^.vartype.def^.needs_inittable)
-            and ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
-                  (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
+            and (pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
+                  not(is_class(pdef(pvarsym(sym)^.vartype.def))) then
            inc(count);
            inc(count);
       end;
       end;
 
 
@@ -2929,7 +2975,7 @@ implementation
          if ((psym(sym)^.typ=varsym) and
          if ((psym(sym)^.typ=varsym) and
             pvarsym(sym)^.vartype.def^.needs_inittable) and
             pvarsym(sym)^.vartype.def^.needs_inittable) and
             ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
             ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
-             (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
+             not(is_class(pvarsym(sym)^.vartype.def))) then
            begin
            begin
               rttilist^.concat(new(pai_const_symbol,init(pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label)));
               rttilist^.concat(new(pai_const_symbol,init(pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label)));
               rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
               rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
@@ -4006,7 +4052,7 @@ Const local_symtable_index : longint = $8001;
        vtableassigned : boolean = false;
        vtableassigned : boolean = false;
 {$endif GDB}
 {$endif GDB}
 
 
-   constructor tobjectdef.init(const n : string;c : pobjectdef);
+   constructor tobjectdef.init(ot : tobjectdeftype;const n : string;c : pobjectdef);
      begin
      begin
         inherited init;
         inherited init;
         deftype:=objectdef;
         deftype:=objectdef;
@@ -4021,6 +4067,20 @@ Const local_symtable_index : longint = $8001;
         symtable^.dataalignment:=packrecordalignment[aktpackrecords];
         symtable^.dataalignment:=packrecordalignment[aktpackrecords];
         set_parent(c);
         set_parent(c);
         objname:=stringdup(n);
         objname:=stringdup(n);
+        lastvtableindex:=0;
+        objecttype:=ot;
+
+        { set up guid }
+        isiidguidvalid:=true; { default null guid }
+        fillchar(iidguid,sizeof(iidguid),0); { default null guid }
+        iidstr:=stringdup(''); { default is empty string }
+
+        { set£p implemented interfaces }
+        if objecttype in [odt_class,odt_interfacecorba] then
+          new(implementedinterfaces,init)
+        else
+          implementedinterfaces:=nil;
+
 {$ifdef GDB}
 {$ifdef GDB}
         writing_stabs:=false;
         writing_stabs:=false;
         classglobalnb:=0;
         classglobalnb:=0;
@@ -4032,9 +4092,11 @@ Const local_symtable_index : longint = $8001;
     constructor tobjectdef.load;
     constructor tobjectdef.load;
       var
       var
          oldread_member : boolean;
          oldread_member : boolean;
+         i,implintfcount: longint;
       begin
       begin
          inherited load;
          inherited load;
          deftype:=objectdef;
          deftype:=objectdef;
+         objecttype:=tobjectdeftype(readbyte);
          savesize:=readlong;
          savesize:=readlong;
          vmt_offset:=readlong;
          vmt_offset:=readlong;
          objname:=stringdup(readstring);
          objname:=stringdup(readstring);
@@ -4042,6 +4104,31 @@ Const local_symtable_index : longint = $8001;
          readsmallset(objectoptions);
          readsmallset(objectoptions);
          has_rtti:=boolean(readbyte);
          has_rtti:=boolean(readbyte);
 
 
+         { load guid }
+         iidstr:=nil;
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+              isiidguidvalid:=boolean(readbyte);
+              readguid(iidguid);
+              iidstr:=stringdup(readstring);
+              lastvtableindex:=readlong;
+           end;
+
+         { load implemented interfaces }
+         if objecttype in [odt_class,odt_interfacecorba] then
+           begin
+             new(implementedinterfaces,init);
+             implintfcount:=readlong;
+             for i:=1 to implintfcount do
+               begin
+                  implementedinterfaces^.addintfref(pdef(readderef));
+                  implementedinterfaces^.ioffsets(i)^:=readlong;
+               end;
+           end
+         else
+           implementedinterfaces:=nil;
+
+
          oldread_member:=read_member;
          oldread_member:=read_member;
          read_member:=true;
          read_member:=true;
          symtable:=new(pstoredsymtable,loadas(objectsymtable));
          symtable:=new(pstoredsymtable,loadas(objectsymtable));
@@ -4054,9 +4141,12 @@ Const local_symtable_index : longint = $8001;
          { the last TOBJECT which is loaded gets }
          { the last TOBJECT which is loaded gets }
          { it !                                  }
          { it !                                  }
          if (childof=nil) and
          if (childof=nil) and
-            is_class and
+            (objecttype=odt_class) and
             (upper(objname^)='TOBJECT') then
             (upper(objname^)='TOBJECT') then
            class_tobject:=@self;
            class_tobject:=@self;
+         if (childof=nil) and (objecttype=odt_interfacecom) and
+           (objname^='IUNKNOWN') then
+           interface_iunknown:=@self;
 {$ifdef GDB}
 {$ifdef GDB}
          writing_stabs:=false;
          writing_stabs:=false;
          classglobalnb:=0;
          classglobalnb:=0;
@@ -4072,6 +4162,9 @@ Const local_symtable_index : longint = $8001;
         if (oo_is_forward in objectoptions) then
         if (oo_is_forward in objectoptions) then
           Message1(sym_e_class_forward_not_resolved,objname^);
           Message1(sym_e_class_forward_not_resolved,objname^);
         stringdispose(objname);
         stringdispose(objname);
+        stringdispose(iidstr);
+        if assigned(implementedinterfaces) then
+          dispose(implementedinterfaces,done);
         inherited done;
         inherited done;
      end;
      end;
 
 
@@ -4079,14 +4172,36 @@ Const local_symtable_index : longint = $8001;
     procedure tobjectdef.write;
     procedure tobjectdef.write;
       var
       var
          oldread_member : boolean;
          oldread_member : boolean;
+         implintfcount : longint;
+         i : longint;
       begin
       begin
          inherited write;
          inherited write;
+         writebyte(byte(objecttype));
          writelong(size);
          writelong(size);
          writelong(vmt_offset);
          writelong(vmt_offset);
          writestring(objname^);
          writestring(objname^);
          writederef(childof);
          writederef(childof);
          writesmallset(objectoptions);
          writesmallset(objectoptions);
          writebyte(byte(has_rtti));
          writebyte(byte(has_rtti));
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+              writebyte(byte(isiidguidvalid));
+              writeguid(iidguid);
+              writestring(iidstr^);
+              writelong(lastvtableindex);
+           end;
+
+         if objecttype in [odt_class,odt_interfacecorba] then
+           begin
+              implintfcount:=implementedinterfaces^.count;
+              writelong(implintfcount);
+              for i:=1 to implintfcount do
+                begin
+                   writederef(implementedinterfaces^.interfaces(i));
+                   writelong(implementedinterfaces^.ioffsets(i)^);
+                end;
+           end;
+
          current_ppu^.writeentry(ibobjectdef);
          current_ppu^.writeentry(ibobjectdef);
 
 
          oldread_member:=read_member;
          oldread_member:=read_member;
@@ -4114,6 +4229,8 @@ Const local_symtable_index : longint = $8001;
          aktrecordsymtable:=symtable;
          aktrecordsymtable:=symtable;
          pstoredsymtable(symtable)^.deref;
          pstoredsymtable(symtable)^.deref;
          aktrecordsymtable:=oldrecsyms;
          aktrecordsymtable:=oldrecsyms;
+         if objecttype in [odt_class,odt_interfacecorba] then
+           implementedinterfaces^.deref;
       end;
       end;
 
 
 
 
@@ -4126,19 +4243,24 @@ Const local_symtable_index : longint = $8001;
         { some options are inherited !! }
         { some options are inherited !! }
         if assigned(c) then
         if assigned(c) then
           begin
           begin
+             { only important for classes }
+             lastvtableindex:=c^.lastvtableindex;
              objectoptions:=objectoptions+(c^.objectoptions*
              objectoptions:=objectoptions+(c^.objectoptions*
                [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
                [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
-             { add the data of the anchestor class }
-             inc(symtable^.datasize,c^.symtable^.datasize);
-             if (oo_has_vmt in objectoptions) and
-                (oo_has_vmt in c^.objectoptions) then
-               dec(symtable^.datasize,target_os.size_of_pointer);
-             { if parent has a vmt field then
-               the offset is the same for the child PM }
-             if (oo_has_vmt in c^.objectoptions) or is_class then
+             if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
                begin
                begin
-                  vmt_offset:=c^.vmt_offset;
-                  include(objectoptions,oo_has_vmt);
+                  { add the data of the anchestor class }
+                  inc(symtable^.datasize,c^.symtable^.datasize);
+                  if (oo_has_vmt in objectoptions) and
+                     (oo_has_vmt in c^.objectoptions) then
+                    dec(symtable^.datasize,target_os.size_of_pointer);
+                  { if parent has a vmt field then
+                    the offset is the same for the child PM }
+                  if (oo_has_vmt in c^.objectoptions) or is_class(@self) then
+                    begin
+                       vmt_offset:=c^.vmt_offset;
+                       include(objectoptions,oo_has_vmt);
+                    end;
                end;
                end;
           end;
           end;
         savesize := symtable^.datasize;
         savesize := symtable^.datasize;
@@ -4147,6 +4269,7 @@ Const local_symtable_index : longint = $8001;
 
 
    procedure tobjectdef.insertvmt;
    procedure tobjectdef.insertvmt;
      begin
      begin
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then exit;
         if (oo_has_vmt in objectoptions) then
         if (oo_has_vmt in objectoptions) then
           internalerror(12345)
           internalerror(12345)
         else
         else
@@ -4172,6 +4295,7 @@ Const local_symtable_index : longint = $8001;
 
 
    procedure tobjectdef.check_forwards;
    procedure tobjectdef.check_forwards;
      begin
      begin
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then exit; { Kaz: ??? }
         pstoredsymtable(symtable)^.check_forwards;
         pstoredsymtable(symtable)^.check_forwards;
         if (oo_is_forward in objectoptions) then
         if (oo_is_forward in objectoptions) then
           begin
           begin
@@ -4250,7 +4374,7 @@ Const local_symtable_index : longint = $8001;
 
 
     function tobjectdef.size : longint;
     function tobjectdef.size : longint;
       begin
       begin
-        if (oo_is_class in objectoptions) then
+        if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
           size:=target_os.size_of_pointer
           size:=target_os.size_of_pointer
         else
         else
           size:=symtable^.datasize;
           size:=symtable^.datasize;
@@ -4266,8 +4390,8 @@ Const local_symtable_index : longint = $8001;
     function tobjectdef.vmtmethodoffset(index:longint):longint;
     function tobjectdef.vmtmethodoffset(index:longint):longint;
       begin
       begin
         { for offset of methods for classes, see rtl/inc/objpash.inc }
         { for offset of methods for classes, see rtl/inc/objpash.inc }
-        if is_class then
-         vmtmethodoffset:=(index+12)*target_os.size_of_pointer
+        if objecttype in [odt_interfacecom,odt_interfacecorba] then
+          vmtmethodoffset:=(index+12)*target_os.size_of_pointer
         else
         else
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
          vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
          vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
@@ -4314,27 +4438,6 @@ Const local_symtable_index : longint = $8001;
     end;
     end;
 
 
 
 
-    function tobjectdef.is_class : boolean;
-      begin
-         is_class:=(oo_is_class in objectoptions);
-      end;
-
-    function tobjectdef.is_object : boolean;
-      begin
-         is_object:=([oo_is_class,oo_is_interface,oo_is_cppclass]*
-           objectoptions)=[];
-      end;
-
-    function tobjectdef.is_interface : boolean;
-      begin
-         is_interface:=(oo_is_interface in objectoptions);
-      end;
-
-    function tobjectdef.is_cppclass : boolean;
-      begin
-         is_cppclass:=(oo_is_cppclass in objectoptions);
-      end;
-
 {$ifdef GDB}
 {$ifdef GDB}
     procedure addprocname(p :pnamedindexobject);
     procedure addprocname(p :pnamedindexobject);
     var virtualind,argnames : string;
     var virtualind,argnames : string;
@@ -4434,7 +4537,7 @@ Const local_symtable_index : longint = $8001;
           storenb, oldrecsize : longint;
           storenb, oldrecsize : longint;
           str_end : string;
           str_end : string;
       begin
       begin
-        if not (is_class) or writing_stabs then
+        if not (objecttype=odt_class) or writing_stabs then
           begin
           begin
             storenb:=globalnb;
             storenb:=globalnb;
             globalnb:=classptrglobalnb;
             globalnb:=classptrglobalnb;
@@ -4488,7 +4591,7 @@ Const local_symtable_index : longint = $8001;
          globalnb:=classglobalnb;
          globalnb:=classglobalnb;
          inc(PglobalTypeCount^);
          inc(PglobalTypeCount^);
          { classes need two type numbers, the globalnb is set to the ptr }
          { classes need two type numbers, the globalnb is set to the ptr }
-         if is_class then
+         if objecttype=odt_class then
            begin
            begin
              classptrglobalnb:=PGlobalTypeCount^;
              classptrglobalnb:=PGlobalTypeCount^;
              globalnb:=classptrglobalnb;
              globalnb:=classptrglobalnb;
@@ -4502,7 +4605,7 @@ Const local_symtable_index : longint = $8001;
      begin
      begin
        if globalnb=0 then
        if globalnb=0 then
          numberstring;
          numberstring;
-       if is_class then
+       if objecttype=odt_class then
          begin
          begin
            onb:=globalnb;
            onb:=globalnb;
            globalnb:=classglobalnb;
            globalnb:=classglobalnb;
@@ -4519,7 +4622,7 @@ Const local_symtable_index : longint = $8001;
      begin
      begin
        if globalnb=0 then
        if globalnb=0 then
          numberstring;
          numberstring;
-       if is_class then
+       if objecttype=odt_class then
          begin
          begin
            onb:=globalnb;
            onb:=globalnb;
            globalnb:=classptrglobalnb;
            globalnb:=classptrglobalnb;
@@ -4533,7 +4636,7 @@ Const local_symtable_index : longint = $8001;
     procedure tobjectdef.concatstabto(asmlist : paasmoutput);
     procedure tobjectdef.concatstabto(asmlist : paasmoutput);
       var st : pstring;
       var st : pstring;
       begin
       begin
-        if not(is_class) then
+        if objecttype<>odt_class then
           begin
           begin
             inherited concatstabto(asmlist);
             inherited concatstabto(asmlist);
             exit;
             exit;
@@ -4576,10 +4679,18 @@ Const local_symtable_index : longint = $8001;
 
 
     procedure tobjectdef.write_init_data;
     procedure tobjectdef.write_init_data;
       begin
       begin
-         if is_class then
-           rttilist^.concat(new(pai_const,init_8bit(tkclass)))
-         else
-           rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+         case objecttype of
+            odt_class:
+              rttilist^.concat(new(pai_const,init_8bit(tkclass)));
+            odt_object:
+              rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+            odt_interfacecom:
+              rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
+            odt_interfacecorba:
+              rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
+          else
+            exit;
+          end;
 
 
          { generate the name }
          { generate the name }
          rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
          rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
@@ -4587,9 +4698,15 @@ Const local_symtable_index : longint = $8001;
 
 
          rttilist^.concat(new(pai_const,init_32bit(size)));
          rttilist^.concat(new(pai_const,init_32bit(size)));
          count:=0;
          count:=0;
-         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
-         rttilist^.concat(new(pai_const,init_32bit(count)));
-         symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           begin
+           end
+         else
+           begin
+              symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
+              rttilist^.concat(new(pai_const,init_32bit(count)));
+              symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
+           end;
       end;
       end;
 
 
 
 
@@ -4597,20 +4714,22 @@ Const local_symtable_index : longint = $8001;
       var
       var
          oldb : boolean;
          oldb : boolean;
       begin
       begin
-         if is_class then
-           needs_inittable:=false
-         else
-           begin
-              { there are recursive calls to needs_inittable possible, }
-              { so we have to change to old value how else should      }
-              { we do that ? check_rec_rtti can't be a nested          }
-              { procedure of needs_rtti !                              }
-              oldb:=binittable;
-              binittable:=false;
-              symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
-              needs_inittable:=binittable;
-              binittable:=oldb;
-           end;
+         case objecttype of
+            odt_interfacecom: needs_inittable:=true;
+            odt_object:
+              begin
+                 { there are recursive calls to needs_inittable possible, }
+                 { so we have to change to old value how else should      }
+                 { we do that ? check_rec_rtti can't be a nested          }
+                 { procedure of needs_rtti !                              }
+                 oldb:=binittable;
+                 binittable:=false;
+                 symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
+                 needs_inittable:=binittable;
+                 binittable:=oldb;
+              end;
+            else needs_inittable:=false;
+         end;
       end;
       end;
 
 
 
 
@@ -4880,17 +4999,24 @@ Const local_symtable_index : longint = $8001;
 
 
     procedure tobjectdef.write_rtti_data;
     procedure tobjectdef.write_rtti_data;
       begin
       begin
-         if is_class then
-           rttilist^.concat(new(pai_const,init_8bit(tkclass)))
+         case objecttype of
+           odt_class: rttilist^.concat(new(pai_const,init_8bit(tkclass)));
+           odt_object: rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+           odt_interfacecom: rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
+           odt_interfacecorba: rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
          else
          else
-           rttilist^.concat(new(pai_const,init_8bit(tkobject)));
+           exit;
+         end;
+
 
 
          { generate the name }
          { generate the name }
          rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
          rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
          rttilist^.concat(new(pai_string,init(objname^)));
          rttilist^.concat(new(pai_string,init(objname^)));
 
 
-         { write class type }
-         rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
+         if objecttype in [odt_interfacecom,odt_interfacecorba] then
+           rttilist^.concat(new(pai_const,init_32bit(0)))
+         else
+           rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
 
 
          { write owner typeinfo }
          { write owner typeinfo }
          if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
          if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
@@ -4932,7 +5058,7 @@ Const local_symtable_index : longint = $8001;
 
 
     function tobjectdef.is_publishable : boolean;
     function tobjectdef.is_publishable : boolean;
       begin
       begin
-         is_publishable:=is_class;
+         is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
       end;
       end;
 
 
     function  tobjectdef.get_rtti_label : string;
     function  tobjectdef.get_rtti_label : string;
@@ -4942,6 +5068,262 @@ Const local_symtable_index : longint = $8001;
          get_rtti_label:=rtti_name;
          get_rtti_label:=rtti_name;
       end;
       end;
 
 
+{****************************************************************************
+                             TIMPLEMENTEDINTERFACES
+****************************************************************************}
+    type
+      pnamemap = ^tnamemap;
+      tnamemap = object(tnamedindexobject)
+        newname: pstring;
+        constructor init(const aname, anewname: string);
+        destructor  done; virtual;
+      end;
+
+    constructor tnamemap.init(const aname, anewname: string);
+      begin
+        inherited initname(name);
+        newname:=stringdup(anewname);
+      end;
+
+    destructor  tnamemap.done;
+      begin
+        stringdispose(newname);
+        inherited done;
+      end;
+
+
+    type
+      pprocdefstore = ^tprocdefstore;
+      tprocdefstore = object(tnamedindexobject)
+        procdef: pprocdef;
+        constructor init(aprocdef: pprocdef);
+      end;
+
+    constructor tprocdefstore.init(aprocdef: pprocdef);
+      begin
+        inherited init;
+        procdef:=aprocdef;
+      end;
+
+
+    type
+      pimplintfentry = ^timplintfentry;
+      timplintfentry = object(tnamedindexobject)
+        intf: pobjectdef;
+        ioffs: longint;
+        namemappings: pdictionary;
+        procdefs: pindexarray;
+        constructor init(aintf: pobjectdef);
+        destructor  done; virtual;
+      end;
+
+    constructor timplintfentry.init(aintf: pobjectdef);
+      begin
+        inherited init;
+        intf:=aintf;
+        ioffs:=-1;
+        namemappings:=nil;
+        procdefs:=nil;
+      end;
+
+    destructor  timplintfentry.done;
+      begin
+        if assigned(namemappings) then
+          dispose(namemappings,done);
+        if assigned(procdefs) then
+          dispose(procdefs,done);
+        inherited done;
+      end;
+
+
+    constructor timplementedinterfaces.init;
+      begin
+        finterfaces.init(1);
+      end;
+
+    destructor  timplementedinterfaces.done;
+      begin
+        finterfaces.done;
+      end;
+
+    function  timplementedinterfaces.count: longint;
+      begin
+        count:=finterfaces.count;
+      end;
+
+    procedure timplementedinterfaces.checkindex(intfindex: longint);
+      begin
+        if (intfindex<1) or (intfindex>count) then
+          InternalError(200006123);
+      end;
+
+    function  timplementedinterfaces.interfaces(intfindex: longint): pobjectdef;
+      begin
+        checkindex(intfindex);
+        interfaces:=pimplintfentry(finterfaces.search(intfindex))^.intf;
+      end;
+
+    function  timplementedinterfaces.ioffsets(intfindex: longint): plongint;
+      begin
+        checkindex(intfindex);
+        ioffsets:=@pimplintfentry(finterfaces.search(intfindex))^.ioffs;
+      end;
+
+    function  timplementedinterfaces.searchintf(def: pdef): longint;
+      var
+        i: longint;
+      begin
+        i:=1;
+        while (i<=count) and (pdef(interfaces(i))<>def) do inc(i);
+        if i<=count then
+          searchintf:=i
+        else
+          searchintf:=-1;
+      end;
+
+    procedure timplementedinterfaces.deref;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            resolvedef(pdef(intf));
+      end;
+
+    procedure timplementedinterfaces.addintfref(def: pdef);
+      begin
+        finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
+      end;
+
+    procedure timplementedinterfaces.addintf(def: pdef);
+      begin
+        if not assigned(def) or (searchintf(def)<>-1) or (def^.deftype<>objectdef) or
+           not (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]) then
+          internalerror(200006124);
+        finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
+      end;
+
+    procedure timplementedinterfaces.clearmappings;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            begin
+             if assigned(namemappings) then
+               dispose(namemappings,done);
+             namemappings:=nil;
+            end;
+      end;
+
+    procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          begin
+            if not assigned(namemappings) then
+              new(namemappings,init);
+            namemappings^.insert(new(pnamemap,init(name,newname)));
+          end;
+      end;
+
+    function  timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
+      begin
+        checkindex(intfindex);
+        if not assigned(nextexist) then
+          with pimplintfentry(finterfaces.search(intfindex))^ do
+            begin
+              if assigned(namemappings) then
+                nextexist:=namemappings^.search(name)
+              else
+                nextexist:=nil;
+            end;
+        if assigned(nextexist) then
+          begin
+            getmappings:=pnamemap(nextexist)^.newname^;
+            nextexist:=pnamemap(nextexist)^.listnext;
+          end
+        else
+          getmappings:='';
+      end;
+
+    procedure timplementedinterfaces.clearimplprocs;
+      var
+        i: longint;
+      begin
+        for i:=1 to count do
+          with pimplintfentry(finterfaces.search(i))^ do
+            begin
+              if assigned(procdefs) then
+                dispose(procdefs,done);
+              procdefs:=nil;
+            end;
+      end;
+
+    procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: pprocdef);
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          begin
+            if not assigned(procdefs) then
+              new(procdefs,init(4));
+            procdefs^.insert(new(pprocdefstore,init(procdef)));
+          end;
+      end;
+
+    function  timplementedinterfaces.implproccount(intfindex: longint): longint;
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          if assigned(procdefs) then
+            implproccount:=procdefs^.count
+          else
+            implproccount:=0;
+      end;
+
+    function  timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): pprocdef;
+      begin
+        checkindex(intfindex);
+        with pimplintfentry(finterfaces.search(intfindex))^ do
+          if assigned(procdefs) then
+            implprocs:=pprocdefstore(procdefs^.search(procindex))^.procdef
+          else
+            internalerror(200006131);
+      end;
+
+    function  timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
+      var
+        possible: boolean;
+        i: longint;
+        iiep1: pindexarray;
+        iiep2: pindexarray;
+      begin
+        checkindex(intfindex);
+        checkindex(remainindex);
+        iiep1:=pimplintfentry(finterfaces.search(intfindex))^.procdefs;
+        iiep2:=pimplintfentry(finterfaces.search(remainindex))^.procdefs;
+        if not assigned(iiep1) then { empty interface is mergeable :-) }
+          begin
+            possible:=true;
+            weight:=0;
+          end
+        else
+          begin
+            possible:=assigned(iiep2) and (iiep1^.count<=iiep2^.count);
+            i:=1;
+            while (possible) and (i<=iiep1^.count) do
+              begin
+                possible:=
+                  pprocdefstore(iiep1^.search(i))^.procdef=
+                  pprocdefstore(iiep2^.search(i))^.procdef;
+                inc(i);
+              end;
+            if possible then
+              weight:=iiep1^.count;
+          end;
+        isimplmergepossible:=possible;
+      end;
+
 {****************************************************************************
 {****************************************************************************
                                 TFORWARDDEF
                                 TFORWARDDEF
 ****************************************************************************}
 ****************************************************************************}
@@ -5078,10 +5460,70 @@ Const local_symtable_index : longint = $8001;
           end;
           end;
      end;
      end;
 
 
+    function is_interfacecom(def: pdef): boolean;
+      begin
+        is_interfacecom:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype=odt_interfacecom);
+      end;
+
+    function is_interfacecorba(def: pdef): boolean;
+      begin
+        is_interfacecorba:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype=odt_interfacecorba);
+      end;
+
+    function is_interface(def: pdef): boolean;
+      begin
+        is_interface:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]);
+      end;
+
+
+    function is_class(def: pdef): boolean;
+      begin
+        is_class:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype=odt_class);
+      end;
+
+    function is_object(def: pdef): boolean;
+      begin
+        is_object:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype=odt_class);
+      end;
+
+    function is_cppclass(def: pdef): boolean;
+      begin
+        is_cppclass:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype=odt_cppclass);
+      end;
+
+    function is_class_or_interface(def: pdef): boolean;
+      begin
+        is_class_or_interface:=
+          assigned(def) and
+          (def^.deftype=objectdef) and
+          (pobjectdef(def)^.objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
+      end;
+
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2000-11-02 12:04:10  pierre
+  Revision 1.4  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.3  2000/11/02 12:04:10  pierre
   * remove RecOffset code, that created problems
   * remove RecOffset code, that created problems
 
 
   Revision 1.2  2000/11/01 23:04:38  peter
   Revision 1.2  2000/11/01 23:04:38  peter

+ 654 - 0
compiler/symdefh.inc

@@ -0,0 +1,654 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
+
+    Interface for the definition types of the symtable
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+
+{************************************************
+                    TDef
+************************************************}
+
+       tdef = object(tsymtableentry)
+          deftype    : tdeftype;
+          typesym    : ptypesym;  { which type the definition was generated this def }
+
+          has_inittable : boolean;
+          { adress of init informations }
+          inittable_label : pasmlabel;
+
+          has_rtti   : boolean;
+          { address of rtti }
+          rtti_label : pasmlabel;
+
+          nextglobal,
+          previousglobal : pdef;
+{$ifdef GDB}
+          globalnb       : word;
+          is_def_stab_written : tdefstabstatus;
+{$endif GDB}
+          constructor init;
+          constructor load;
+          destructor  done;virtual;
+          procedure deref;virtual;
+          function  typename:string;
+          procedure write;virtual;
+          function  size:longint;virtual;
+          function  alignment:longint;virtual;
+          function  gettypename:string;virtual;
+          function  is_publishable : boolean;virtual;
+          function  is_in_current : boolean;
+          procedure correct_owner_symtable; { registers enumdef inside objects or
+                                              record directly in the owner symtable !! }
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+          function  NumberString:string;
+          procedure set_globalnb;virtual;
+          function  allstabstring : pchar;
+{$endif GDB}
+          { init. tables }
+          function  needs_inittable : boolean;virtual;
+          procedure generate_inittable;
+          function  get_inittable_label : pasmlabel;
+          { the default implemenation calls write_rtti_data     }
+          { if init and rtti data is different these procedures }
+          { must be overloaded                                  }
+          procedure write_init_data;virtual;
+          procedure write_child_init_data;virtual;
+          { rtti }
+          procedure write_rtti_name;
+          function  get_rtti_label : string;virtual;
+          procedure generate_rtti;virtual;
+          procedure write_rtti_data;virtual;
+          procedure write_child_rtti_data;virtual;
+          function is_intregable : boolean;
+          function is_fpuregable : boolean;
+       private
+          savesize  : longint;
+       end;
+
+       targconvtyp = (act_convertable,act_equal,act_exact);
+
+       tvarspez = (vs_value,vs_const,vs_var,vs_out);
+
+       pparaitem = ^tparaitem;
+       tparaitem = object(tlinkedlist_item)
+          paratype     : ttype;
+          paratyp      : tvarspez;
+          argconvtyp   : targconvtyp;
+          convertlevel : byte;
+          register     : tregister;
+          defaultvalue : psym; { pconstsym }
+       end;
+
+       { this is only here to override the count method,
+         which can't be used }
+       pparalinkedlist = ^tparalinkedlist;
+       tparalinkedlist = object(tlinkedlist)
+          function count:longint;
+       end;
+
+       tfiletyp = (ft_text,ft_typed,ft_untyped);
+
+       pfiledef = ^tfiledef;
+       tfiledef = object(tdef)
+          filetyp : tfiletyp;
+          typedfiletype : ttype;
+          constructor inittext;
+          constructor inituntyped;
+          constructor inittyped(const tt : ttype);
+          constructor inittypeddef(p : pdef);
+          constructor load;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  gettypename:string;virtual;
+          procedure setsize;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+       end;
+
+       pformaldef = ^tformaldef;
+       tformaldef = object(tdef)
+          constructor init;
+          constructor load;
+          procedure write;virtual;
+          function  gettypename:string;virtual;
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+       end;
+
+       pforwarddef = ^tforwarddef;
+       tforwarddef = object(tdef)
+          tosymname : string;
+          forwardpos : tfileposinfo;
+          constructor init(const s:string;const pos : tfileposinfo);
+          function  gettypename:string;virtual;
+       end;
+
+       perrordef = ^terrordef;
+       terrordef = object(tdef)
+          constructor init;
+          function  gettypename:string;virtual;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+{$endif GDB}
+       end;
+
+       { tpointerdef and tclassrefdef should get a common
+         base class, but I derived tclassrefdef from tpointerdef
+         to avoid problems with bugs (FK)
+       }
+
+       ppointerdef = ^tpointerdef;
+       tpointerdef = object(tdef)
+          pointertype : ttype;
+          is_far : boolean;
+          constructor init(const tt : ttype);
+          constructor initfar(const tt : ttype);
+          constructor initdef(p : pdef);
+          constructor initfardef(p : pdef);
+          constructor load;
+          destructor  done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  gettypename:string;virtual;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          {private}
+          public
+            { I don't know the use of this FK }
+            pointertypeis_forwarddef: boolean;
+       end;
+
+       pprocdef = ^tprocdef;
+       pimplementedinterfaces = ^timplementedinterfaces;
+
+       pobjectdef = ^tobjectdef;
+       tobjectdef = object(tdef)
+          childof  : pobjectdef;
+          objname  : pstring;
+          symtable : psymtable;
+          objectoptions : tobjectoptions;
+          { to be able to have a variable vmt position }
+          { and no vmt field for objects without virtuals }
+          vmt_offset : longint;
+{$ifdef GDB}
+          classglobalnb,
+          classptrglobalnb : word;
+          writing_stabs : boolean;
+{$endif GDB}
+          objecttype : tobjectdeftype;
+          isiidguidvalid: boolean;
+          iidguid: TGUID;
+          iidstr: pstring;
+          lastvtableindex: longint;
+          { store implemented interfaces defs and name mappings }
+          implementedinterfaces: pimplementedinterfaces;
+
+          constructor init(odt : tobjectdeftype; const n : string;c : pobjectdef);
+          constructor load;
+          destructor  done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  size : longint;virtual;
+          function  alignment:longint;virtual;
+          function  vmtmethodoffset(index:longint):longint;
+          function  is_publishable : boolean;virtual;
+          function  vmt_mangledname : string;
+          function  rtti_name : string;
+          procedure check_forwards;
+          function  is_related(d : pobjectdef) : boolean;
+          function  next_free_name_index : longint;
+          procedure insertvmt;
+          procedure set_parent(c : pobjectdef);
+          function searchdestructor : pprocdef;
+          { debug }
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+          procedure set_globalnb;virtual;
+          function  classnumberstring : string;
+          function  classptrnumberstring : string;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          { init/final }
+          function  needs_inittable : boolean;virtual;
+          procedure write_init_data;virtual;
+          procedure write_child_init_data;virtual;
+          { rtti }
+          function  get_rtti_label : string;virtual;
+          procedure generate_rtti;virtual;
+          procedure write_rtti_data;virtual;
+          procedure write_child_rtti_data;virtual;
+          function generate_field_table : pasmlabel;
+       end;
+
+       timplementedinterfaces = object
+         constructor init;
+         destructor  done; virtual;
+
+         function  count: longint;
+         function  interfaces(intfindex: longint): pobjectdef;
+         function  ioffsets(intfindex: longint): plongint;
+         function  searchintf(def: pdef): longint;
+         procedure addintf(def: pdef);
+
+         procedure deref;
+         procedure addintfref(def: pdef);
+
+         procedure clearmappings;
+         procedure addmappings(intfindex: longint; const name, newname: string);
+         function  getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
+
+         procedure clearimplprocs;
+         procedure addimplproc(intfindex: longint; procdef: pprocdef);
+         function  implproccount(intfindex: longint): longint;
+         function  implprocs(intfindex: longint; procindex: longint): pprocdef;
+         function  isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
+
+       private
+         finterfaces: tindexarray;
+         procedure checkindex(intfindex: longint);
+       end;
+
+
+       pclassrefdef = ^tclassrefdef;
+       tclassrefdef = object(tpointerdef)
+          constructor init(def : pdef);
+          constructor load;
+          procedure write;virtual;
+          function gettypename:string;virtual;
+          { debug }
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+       end;
+
+       parraydef = ^tarraydef;
+       tarraydef = object(tdef)
+       private
+          rangenr    : longint;
+       public
+          lowrange,
+          highrange  : longint;
+          elementtype,
+          rangetype  : ttype;
+          IsDynamicArray,
+          IsVariant,
+          IsConstructor,
+          IsArrayOfConst : boolean;
+          function gettypename:string;virtual;
+          function elesize : longint;
+          constructor init(l,h : longint;rd : pdef);
+          constructor load;
+          procedure write;virtual;
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          procedure deref;virtual;
+          function size : longint;virtual;
+          function alignment : longint;virtual;
+          { generates the ranges needed by the asm instruction BOUND (i386)
+            or CMP2 (Motorola) }
+          procedure genrangecheck;
+
+          { returns the label of the range check string }
+          function getrangecheckstring : string;
+          function needs_inittable : boolean;virtual;
+          procedure write_rtti_data;virtual;
+          procedure write_child_rtti_data;virtual;
+       end;
+
+       precorddef = ^trecorddef;
+       trecorddef = object(tdef)
+          symtable : psymtable;
+          constructor init(p : psymtable);
+          constructor load;
+          destructor done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  size:longint;virtual;
+          function  alignment : longint;virtual;
+          function  gettypename:string;virtual;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          { init/final }
+          procedure write_init_data;virtual;
+          procedure write_child_init_data;virtual;
+          function  needs_inittable : boolean;virtual;
+          { rtti }
+          procedure write_rtti_data;virtual;
+          procedure write_child_rtti_data;virtual;
+       end;
+
+       porddef = ^torddef;
+       torddef = object(tdef)
+        private
+          rangenr  : longint;
+        public
+          low,high : longint;
+          typ      : tbasetype;
+          constructor init(t : tbasetype;v,b : longint);
+          constructor load;
+          procedure write;virtual;
+          function  is_publishable : boolean;virtual;
+          function  gettypename:string;virtual;
+          procedure setsize;
+          { generates the ranges needed by the asm instruction BOUND }
+          { or CMP2 (Motorola)                                       }
+          procedure genrangecheck;
+          function  getrangecheckstring : string;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+{$endif GDB}
+          { rtti }
+          procedure write_rtti_data;virtual;
+       end;
+
+       pfloatdef = ^tfloatdef;
+       tfloatdef = object(tdef)
+          typ : tfloattype;
+          constructor init(t : tfloattype);
+          constructor load;
+          procedure write;virtual;
+          function  gettypename:string;virtual;
+          function  is_publishable : boolean;virtual;
+          procedure setsize;
+          { debug }
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+{$endif GDB}
+          { rtti }
+          procedure write_rtti_data;virtual;
+       end;
+
+       pabstractprocdef = ^tabstractprocdef;
+       tabstractprocdef = object(tdef)
+          { saves a definition to the return type }
+          rettype         : ttype;
+          proctypeoption  : tproctypeoption;
+          proccalloptions : tproccalloptions;
+          procoptions     : tprocoptions;
+          para            : pparalinkedlist;
+          maxparacount,
+          minparacount    : longint;
+          symtablelevel   : byte;
+          fpu_used        : byte;    { how many stack fpu must be empty }
+          constructor init;
+          constructor load;
+          destructor done;virtual;
+          procedure  write;virtual;
+          procedure deref;virtual;
+          procedure concatpara(tt:ttype;vsp : tvarspez;defval:psym);
+          function  para_size(alignsize:longint) : longint;
+          function  demangled_paras : string;
+          function  proccalloption2str : string;
+          procedure test_if_fpu_result;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+       end;
+
+       pprocvardef = ^tprocvardef;
+       tprocvardef = object(tabstractprocdef)
+          constructor init;
+          constructor load;
+          procedure write;virtual;
+          function  size : longint;virtual;
+          function gettypename:string;virtual;
+          function is_publishable : boolean;virtual;
+          { debug }
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput); virtual;
+{$endif GDB}
+          { rtti }
+          procedure write_child_rtti_data;virtual;
+          procedure write_rtti_data;virtual;
+       end;
+
+       tmessageinf = record
+         case integer of
+           0 : (str : pchar);
+           1 : (i : longint);
+       end;
+
+       tprocdef = object(tabstractprocdef)
+       private
+          _mangledname : pstring;
+       public
+          extnumber  : longint;
+          messageinf : tmessageinf;
+          nextoverloaded : pprocdef;
+          { where is this function defined, needed here because there
+            is only one symbol for all overloaded functions }
+          fileinfo : tfileposinfo;
+          { pointer to the local symbol table }
+          localst : psymtable;
+          { pointer to the parameter symbol table }
+          parast : psymtable;
+          { symbol owning this definition }
+          procsym : pprocsym;
+          { browser info }
+          lastref,
+          defref,
+          crossref,
+          lastwritten : pref;
+          refcount : longint;
+          _class : pobjectdef;
+          { it's a tree, but this not easy to handle }
+          { used for inlined procs                   }
+          code : pointer;
+          { info about register variables (JM) }
+          regvarinfo: pointer;
+          { true, if the procedure is only declared }
+          { (forward procedure) }
+          forwarddef,
+          { true if the procedure is declared in the interface }
+          interfacedef : boolean;
+          { true if the procedure has a forward declaration }
+          hasforward : boolean;
+          { check the problems of manglednames }
+          count      : boolean;
+          is_used    : boolean;
+          { small set which contains the modified registers }
+{$ifdef newcg}
+          usedregisters : tregisterset;
+{$else newcg}
+          usedregisters : longint;
+{$endif newcg}
+          constructor init;
+          constructor load;
+          destructor  done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  haspara:boolean;
+          function  mangledname : string;
+          procedure setmangledname(const s : string);
+          procedure load_references;
+          function  write_references : boolean;
+{$ifdef dummy}
+          function  procname: string;
+{$endif dummy}
+          function  cplusplusmangledname : string;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          { browser }
+{$ifdef BrowserLog}
+          procedure add_to_browserlog;
+{$endif BrowserLog}
+       end;
+
+       pstringdef = ^tstringdef;
+       tstringdef = object(tdef)
+          string_typ : tstringtype;
+          len        : longint;
+          constructor shortinit(l : byte);
+          constructor shortload;
+          constructor longinit(l : longint);
+          constructor longload;
+          constructor ansiinit(l : longint);
+          constructor ansiload;
+          constructor wideinit(l : longint);
+          constructor wideload;
+          function  stringtypname:string;
+          function  size : longint;virtual;
+          procedure write;virtual;
+          function  gettypename:string;virtual;
+          function  is_publishable : boolean;virtual;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          { init/final }
+          function  needs_inittable : boolean;virtual;
+          { rtti }
+          procedure write_rtti_data;virtual;
+       end;
+
+       penumdef = ^tenumdef;
+       tenumdef = object(tdef)
+          rangenr,
+          minval,
+          maxval    : longint;
+          has_jumps : boolean;
+          firstenum : penumsym;
+          basedef   : penumdef;
+          constructor init;
+          constructor init_subrange(_basedef:penumdef;_min,_max:longint);
+          constructor load;
+          destructor done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  gettypename:string;virtual;
+          function  is_publishable : boolean;virtual;
+          procedure calcsavesize;
+          procedure setmax(_max:longint);
+          procedure setmin(_min:longint);
+          function  min:longint;
+          function  max:longint;
+          function  getrangecheckstring:string;
+          procedure genrangecheck;
+          { debug }
+{$ifdef GDB}
+          function stabstring : pchar;virtual;
+{$endif GDB}
+          { rtti }
+          procedure write_child_rtti_data;virtual;
+          procedure write_rtti_data;virtual;
+       end;
+
+       psetdef = ^tsetdef;
+       tsetdef = object(tdef)
+          elementtype : ttype;
+          settype : tsettype;
+          constructor init(s : pdef;high : longint);
+          constructor load;
+          destructor  done;virtual;
+          procedure write;virtual;
+          procedure deref;virtual;
+          function  gettypename:string;virtual;
+          function  is_publishable : boolean;virtual;
+          { debug }
+{$ifdef GDB}
+          function  stabstring : pchar;virtual;
+          procedure concatstabto(asmlist : paasmoutput);virtual;
+{$endif GDB}
+          { rtti }
+          procedure write_rtti_data;virtual;
+          procedure write_child_rtti_data;virtual;
+       end;
+
+{
+  $Log$
+  Revision 1.15  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.14  2000/10/31 22:02:52  peter
+    * symtable splitted, no real code changes
+
+  Revision 1.13  2000/10/21 18:16:12  florian
+    * a lot of changes:
+       - basic dyn. array support
+       - basic C++ support
+       - some work for interfaces done
+       ....
+
+  Revision 1.12  2000/10/15 07:47:52  peter
+    * unit names and procedure names are stored mixed case
+
+  Revision 1.11  2000/10/14 10:14:53  peter
+    * moehrendorf oct 2000 rewrite
+
+  Revision 1.10  2000/09/24 15:06:29  peter
+    * use defines.inc
+
+  Revision 1.9  2000/09/19 23:08:03  pierre
+   * fixes for local class debuggging problem (merged)
+
+  Revision 1.8  2000/08/21 11:27:44  pierre
+   * fix the stabs problems
+
+  Revision 1.7  2000/08/06 19:39:28  peter
+    * default parameters working !
+
+  Revision 1.6  2000/08/06 14:17:15  peter
+    * overload fixes (merged)
+
+  Revision 1.5  2000/08/03 13:17:26  jonas
+    + allow regvars to be used inside inlined procs, which required  the
+      following changes:
+        + load regvars in genentrycode/free them in genexitcode (cgai386)
+        * moved all regvar related code to new regvars unit
+        + added pregvarinfo type to hcodegen
+        + added regvarinfo field to tprocinfo (symdef/symdefh)
+        * deallocate the regvars of the caller in secondprocinline before
+          inlining the called procedure and reallocate them afterwards
+
+  Revision 1.4  2000/08/02 19:49:59  peter
+    * first things for default parameters
+
+  Revision 1.3  2000/07/13 12:08:27  michael
+  + patched to 1.1.0 with former 1.09patch from peter
+
+  Revision 1.2  2000/07/13 11:32:49  michael
+  + removed logs
+
+}

+ 782 - 0
compiler/symppu.inc

@@ -0,0 +1,782 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
+
+    Implementation of the reading of PPU Files for the symtable
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+
+    const
+{$ifdef FPC}
+       ppubufsize=32768;
+{$ELSE}
+    {$IFDEF USEOVERLAY}
+       ppubufsize=512;
+    {$ELSE}
+       ppubufsize=4096;
+    {$ENDIF}
+{$ENDIF}
+
+{$define ORDERSOURCES}
+
+{*****************************************************************************
+                                 PPU Writing
+*****************************************************************************}
+
+    procedure writebyte(b:byte);
+      begin
+        current_ppu^.putbyte(b);
+      end;
+
+
+    procedure writeword(w:word);
+      begin
+        current_ppu^.putword(w);
+      end;
+
+
+    procedure writelong(l:longint);
+      begin
+        current_ppu^.putlongint(l);
+      end;
+
+
+    procedure writereal(d:bestreal);
+      begin
+        current_ppu^.putreal(d);
+      end;
+
+
+    procedure writestring(const s:string);
+      begin
+        current_ppu^.putstring(s);
+      end;
+
+
+    procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
+      begin
+        current_ppu^.putdata(s,sizeof(tnormalset));
+      end;
+
+
+    procedure writesmallset(var s; size: longint);
+      var
+        tmpl: longint;
+      begin
+        { The minimum size of a set under Delphi isn't 32 bit }
+        { this is only binary compatible with FPC if first element's value of the set is 0 }
+        tmpl:=0; move(s,tmpl,size);
+        current_ppu^.putdata(tmpl,4);
+        {old code: current_ppu^.putdata(s,4);}
+      end;
+
+    procedure writeguid(var g: tguid);
+      begin
+        current_ppu^.putdata(g,sizeof(g));
+      end;
+
+    { posinfo is not relevant for changes in PPU }
+    procedure writeposinfo(const p:tfileposinfo);
+      var
+        oldcrc : boolean;
+      begin
+        oldcrc:=current_ppu^.do_crc;
+        current_ppu^.do_crc:=false;
+        current_ppu^.putword(p.fileindex);
+        current_ppu^.putlongint(p.line);
+        current_ppu^.putword(p.column);
+        current_ppu^.do_crc:=oldcrc;
+      end;
+
+
+    procedure writederef(p : psymtableentry);
+      begin
+        if p=nil then
+         current_ppu^.putbyte(ord(derefnil))
+        else
+         begin
+           { Static symtable ? }
+           if p^.owner^.symtabletype=staticsymtable then
+            begin
+              current_ppu^.putbyte(ord(derefaktstaticindex));
+              current_ppu^.putword(p^.indexnr);
+            end
+           { Local record/object symtable ? }
+           else if (p^.owner=aktrecordsymtable) then
+            begin
+              current_ppu^.putbyte(ord(derefaktrecordindex));
+              current_ppu^.putword(p^.indexnr);
+            end
+           { Local local/para symtable ? }
+           else if (p^.owner=aktlocalsymtable) then
+            begin
+              current_ppu^.putbyte(ord(derefaktlocal));
+              current_ppu^.putword(p^.indexnr);
+            end
+           else
+            begin
+              current_ppu^.putbyte(ord(derefindex));
+              current_ppu^.putword(p^.indexnr);
+           { Current unit symtable ? }
+              repeat
+                if not assigned(p) then
+                 internalerror(556655);
+                case p^.owner^.symtabletype of
+                 { when writing the pseudo PPU file
+                   to get CRC values the globalsymtable is not yet
+                   a unitsymtable PM }
+                  globalsymtable,
+                  unitsymtable :
+                    begin
+                      { check if the unit is available in the uses
+                        clause, else it's an error }
+                      if p^.owner^.unitid=$ffff then
+                       internalerror(55665566);
+                      current_ppu^.putbyte(ord(derefunit));
+                      current_ppu^.putword(p^.owner^.unitid);
+                      break;
+                    end;
+                  staticsymtable :
+                    begin
+                      current_ppu^.putbyte(ord(derefaktstaticindex));
+                      current_ppu^.putword(p^.indexnr);
+                      break;
+                    end;
+                  localsymtable :
+                    begin
+                      p:=p^.owner^.defowner;
+                      current_ppu^.putbyte(ord(dereflocal));
+                      current_ppu^.putword(p^.indexnr);
+                    end;
+                  parasymtable :
+                    begin
+                      p:=p^.owner^.defowner;
+                      current_ppu^.putbyte(ord(derefpara));
+                      current_ppu^.putword(p^.indexnr);
+                    end;
+                  objectsymtable,
+                  recordsymtable :
+                    begin
+                      p:=p^.owner^.defowner;
+                      current_ppu^.putbyte(ord(derefrecord));
+                      current_ppu^.putword(p^.indexnr);
+                    end;
+                  else
+                    internalerror(556656);
+                end;
+              until false;
+            end;
+         end;
+      end;
+
+    procedure writedefref(p : pdef);
+      begin
+        writederef(p);
+      end;
+
+    procedure writesymref(p : psym);
+      begin
+        writederef(p);
+      end;
+
+    procedure writesourcefiles;
+      var
+        hp    : pinputfile;
+{$ifdef ORDERSOURCES}
+        i,j : longint;
+{$endif ORDERSOURCES}
+      begin
+      { second write the used source files }
+        current_ppu^.do_crc:=false;
+        hp:=current_module^.sourcefiles^.files;
+{$ifdef ORDERSOURCES}
+      { write source files directly in good order }
+        j:=0;
+        while assigned(hp) do
+          begin
+            inc(j);
+            hp:=hp^.ref_next;
+          end;
+        while j>0 do
+          begin
+            hp:=current_module^.sourcefiles^.files;
+            for i:=1 to j-1 do
+              hp:=hp^.ref_next;
+            current_ppu^.putstring(hp^.name^);
+            dec(j);
+         end;
+{$else not ORDERSOURCES}
+        while assigned(hp) do
+         begin
+         { only name and extension }
+           current_ppu^.putstring(hp^.name^);
+           hp:=hp^.ref_next;
+         end;
+{$endif ORDERSOURCES}
+        current_ppu^.writeentry(ibsourcefiles);
+        current_ppu^.do_crc:=true;
+      end;
+
+    procedure writeusedmacros;
+      var
+        hp    : pmacrosym;
+        i     : longint;
+      begin
+      { second write the used source files }
+        current_ppu^.do_crc:=false;
+        for i:=1 to macros^.symindex^.count do
+         begin
+           hp:=pmacrosym(macros^.symindex^.search(i));
+         { only used or init defined macros are stored }
+           if hp^.is_used or hp^.defined_at_startup then
+             begin
+               current_ppu^.putstring(hp^.name);
+               current_ppu^.putbyte(byte(hp^.defined_at_startup));
+               current_ppu^.putbyte(byte(hp^.is_used));
+             end;
+         end;
+        current_ppu^.writeentry(ibusedmacros);
+        current_ppu^.do_crc:=true;
+      end;
+
+
+    procedure writeusedunit;
+      var
+        hp      : pused_unit;
+      begin
+        numberunits;
+        hp:=pused_unit(current_module^.used_units.first);
+        while assigned(hp) do
+         begin
+           { implementation units should not change
+             the CRC PM }
+           current_ppu^.do_crc:=hp^.in_interface;
+           current_ppu^.putstring(hp^.name^);
+           { the checksum should not affect the crc of this unit ! (PFV) }
+           current_ppu^.do_crc:=false;
+           current_ppu^.putlongint(hp^.checksum);
+           current_ppu^.putlongint(hp^.interface_checksum);
+           current_ppu^.putbyte(byte(hp^.in_interface));
+           current_ppu^.do_crc:=true;
+           hp:=pused_unit(hp^.next);
+         end;
+        current_ppu^.do_interface_crc:=true;
+        current_ppu^.writeentry(ibloadunit);
+      end;
+
+
+    procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
+      var
+        hcontainer : tlinkcontainer;
+        s : string;
+        mask : longint;
+      begin
+        hcontainer.init;
+        while not p.empty do
+         begin
+           s:=p.get(mask);
+           if strippath then
+            current_ppu^.putstring(SplitFileName(s))
+           else
+            current_ppu^.putstring(s);
+           current_ppu^.putlongint(mask);
+           hcontainer.insert(s,mask);
+         end;
+        current_ppu^.writeentry(id);
+        p:=hcontainer;
+      end;
+
+
+    procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
+      begin
+         Message1(unit_u_ppu_write,s);
+
+       { create unit flags }
+         with Current_Module^ do
+          begin
+{$ifdef GDB}
+            if cs_gdb_dbx in aktglobalswitches then
+             flags:=flags or uf_has_dbx;
+{$endif GDB}
+            if target_os.endian=endian_big then
+             flags:=flags or uf_big_endian;
+            if cs_browser in aktmoduleswitches then
+             flags:=flags or uf_has_browser;
+            if cs_local_browser in aktmoduleswitches then
+             flags:=flags or uf_local_browser;
+          end;
+
+{$ifdef Test_Double_checksum_write}
+        If only_crc then
+          Assign(CRCFile,s+'.INT')
+        else
+          Assign(CRCFile,s+'.IMP');
+        Rewrite(CRCFile);
+{$endif def Test_Double_checksum_write}
+       { open ppufile }
+         current_ppu:=new(pppufile,init(s));
+         current_ppu^.crc_only:=only_crc;
+         if not current_ppu^.create then
+           Message(unit_f_ppu_cannot_write);
+
+{$ifdef Test_Double_checksum}
+         if only_crc then
+           begin
+              new(current_ppu^.crc_test);
+              new(current_ppu^.crc_test2);
+           end
+         else
+           begin
+             current_ppu^.crc_test:=Current_Module^.crc_array;
+             current_ppu^.crc_index:=Current_Module^.crc_size;
+             current_ppu^.crc_test2:=Current_Module^.crc_array2;
+             current_ppu^.crc_index2:=Current_Module^.crc_size2;
+           end;
+{$endif def Test_Double_checksum}
+
+         current_ppu^.change_endian:=source_os.endian<>target_os.endian;
+       { write symbols and definitions }
+         unittable^.writeasunit;
+
+       { flush to be sure }
+         current_ppu^.flush;
+       { create and write header }
+         current_ppu^.header.size:=current_ppu^.size;
+         current_ppu^.header.checksum:=current_ppu^.crc;
+         current_ppu^.header.interface_checksum:=current_ppu^.interface_crc;
+         current_ppu^.header.compiler:=wordversion;
+         current_ppu^.header.cpu:=word(target_cpu);
+         current_ppu^.header.target:=word(target_info.target);
+         current_ppu^.header.flags:=current_module^.flags;
+         If not only_crc then
+           current_ppu^.writeheader;
+       { save crc in current_module also }
+         current_module^.crc:=current_ppu^.crc;
+         current_module^.interface_crc:=current_ppu^.interface_crc;
+         if only_crc then
+          begin
+{$ifdef Test_Double_checksum}
+            Current_Module^.crc_array:=current_ppu^.crc_test;
+            current_ppu^.crc_test:=nil;
+            Current_Module^.crc_size:=current_ppu^.crc_index2;
+            Current_Module^.crc_array2:=current_ppu^.crc_test2;
+            current_ppu^.crc_test2:=nil;
+            Current_Module^.crc_size2:=current_ppu^.crc_index2;
+{$endif def Test_Double_checksum}
+            closecurrentppu;
+          end;
+{$ifdef Test_Double_checksum_write}
+        close(CRCFile);
+{$endif Test_Double_checksum_write}
+      end;
+
+
+    procedure closecurrentppu;
+      begin
+{$ifdef Test_Double_checksum}
+         if assigned(current_ppu^.crc_test) then
+           dispose(current_ppu^.crc_test);
+         if assigned(current_ppu^.crc_test2) then
+           dispose(current_ppu^.crc_test2);
+{$endif Test_Double_checksum}
+       { close }
+         current_ppu^.close;
+         dispose(current_ppu,done);
+         current_ppu:=nil;
+      end;
+
+
+{*****************************************************************************
+                                 PPU Reading
+*****************************************************************************}
+
+    function readbyte:byte;
+      begin
+        readbyte:=current_ppu^.getbyte;
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    function readword:word;
+      begin
+        readword:=current_ppu^.getword;
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    function readlong:longint;
+      begin
+        readlong:=current_ppu^.getlongint;
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    function readreal : bestreal;
+      begin
+        readreal:=current_ppu^.getreal;
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    function readstring : string;
+      begin
+        readstring:=current_ppu^.getstring;
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    procedure readnormalset(var s);   {You cannot pass an array [0..31] of byte.}
+      begin
+        current_ppu^.getdata(s,sizeof(tnormalset));
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    procedure readsmallset(var s;size: longint);
+      var
+        tmpl: longint;
+      begin
+        { The minimum size of a set under Delphi isn't 32 bit }
+        { this is only binary compatible if first element's value of the set is 0 }
+        current_ppu^.getdata(tmpl,4);
+        move(tmpl,s,size);
+        {old code: current_ppu^.getdata(s,4); }
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+
+    procedure readguid(var g: tguid);
+      begin
+        current_ppu^.getdata(g,sizeof(g));
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
+    procedure readposinfo(var p:tfileposinfo);
+      begin
+        p.fileindex:=current_ppu^.getword;
+        p.line:=current_ppu^.getlongint;
+        p.column:=current_ppu^.getword;
+      end;
+
+
+    function readderef : pderef;
+      var
+        hp,p : pderef;
+        b : tdereftype;
+      begin
+        p:=nil;
+        repeat
+          hp:=p;
+          b:=tdereftype(current_ppu^.getbyte);
+          case b of
+            derefnil :
+              break;
+            derefunit,
+            derefaktrecordindex,
+            derefaktlocal,
+            derefaktstaticindex :
+              begin
+                new(p,init(b,current_ppu^.getword));
+                p^.next:=hp;
+                break;
+              end;
+            derefindex,
+            dereflocal,
+            derefpara,
+            derefrecord :
+              begin
+                new(p,init(b,current_ppu^.getword));
+                p^.next:=hp;
+              end;
+          end;
+        until false;
+        readderef:=p;
+      end;
+
+    function readdefref : pdef;
+      begin
+        readdefref:=pdef(readderef);
+      end;
+
+    function readsymref : psym;
+      begin
+        readsymref:=psym(readderef);
+      end;
+
+    procedure readusedmacros;
+      var
+        hs : string;
+        mac : pmacrosym;
+        was_defined_at_startup,
+        was_used : boolean;
+      begin
+        while not current_ppu^.endofentry do
+         begin
+           hs:=current_ppu^.getstring;
+           was_defined_at_startup:=boolean(current_ppu^.getbyte);
+           was_used:=boolean(current_ppu^.getbyte);
+           mac:=pmacrosym(macros^.search(hs));
+           if assigned(mac) then
+             begin
+{$ifndef EXTDEBUG}
+           { if we don't have the sources why tell }
+              if current_module^.sources_avail then
+{$endif ndef EXTDEBUG}
+               if (not was_defined_at_startup) and
+                  was_used and
+                  mac^.defined_at_startup then
+                Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
+             end
+           else { not assigned }
+             if was_defined_at_startup and
+                was_used then
+              Message2(unit_h_cond_not_set_in_last_compile,hs,current_module^.mainsource^);
+         end;
+      end;
+
+    procedure readsourcefiles;
+      var
+        temp,hs       : string;
+        temp_dir      : string;
+{$ifdef ORDERSOURCES}
+        main_dir      : string;
+{$endif ORDERSOURCES}
+        incfile_found,
+        main_found,
+        is_main       : boolean;
+        ppufiletime,
+        source_time   : longint;
+        hp            : pinputfile;
+      begin
+        ppufiletime:=getnamedfiletime(current_module^.ppufilename^);
+        current_module^.sources_avail:=true;
+{$ifdef ORDERSOURCES}
+        is_main:=true;
+        main_dir:='';
+{$endif ORDERSOURCES}
+        while not current_ppu^.endofentry do
+         begin
+           hs:=current_ppu^.getstring;
+{$ifndef ORDERSOURCES}
+           is_main:=current_ppu^.endofentry;
+{$endif ORDERSOURCES}
+           temp_dir:='';
+           if (current_module^.flags and uf_in_library)<>0 then
+            begin
+              current_module^.sources_avail:=false;
+              temp:=' library';
+            end
+           else if pos('Macro ',hs)=1 then
+            begin
+              { we don't want to find this file }
+              { but there is a problem with file indexing !! }
+              temp:='';
+            end
+           else
+            begin
+              { check the date of the source files }
+              Source_Time:=GetNamedFileTime(current_module^.path^+hs);
+              incfile_found:=false;
+              main_found:=false;
+              if Source_Time<>-1 then
+                hs:=current_module^.path^+hs
+{$ifdef ORDERSOURCES}
+              else if not(is_main) then
+                begin
+                  Source_Time:=GetNamedFileTime(main_dir+hs);
+                  if Source_Time<>-1 then
+                    hs:=main_dir+hs;
+                end
+{$endif def ORDERSOURCES}
+                   ;
+              if (Source_Time=-1) then
+                begin
+                  if is_main then
+                    temp_dir:=unitsearchpath.FindFile(hs,main_found)
+                  else
+                    temp_dir:=includesearchpath.FindFile(hs,incfile_found);
+                  if incfile_found or main_found then
+                   begin
+                     hs:=temp_dir+hs;
+                     Source_Time:=GetNamedFileTime(hs);
+                   end
+                end;
+              if Source_Time=-1 then
+               begin
+                 current_module^.sources_avail:=false;
+                 temp:=' not found';
+               end
+              else
+               begin
+                 if main_found then
+                   main_dir:=temp_dir;
+                 { time newer? But only allow if the file is not searched
+                   in the include path (PFV), else you've problems with
+                   units which use the same includefile names }
+                 if incfile_found then
+                  temp:=' found'
+                 else
+                  begin
+                    temp:=' time '+filetimestring(source_time);
+                    if (source_time>ppufiletime) then
+                     begin
+                       current_module^.do_compile:=true;
+                       current_module^.recompile_reason:=rr_sourcenewer;
+                       temp:=temp+' *'
+                     end;
+                  end;
+               end;
+              new(hp,init(hs));
+              { the indexing is wrong here PM }
+              current_module^.sourcefiles^.register_file(hp);
+            end;
+{$ifdef ORDERSOURCES}
+           if is_main then
+             begin
+               stringdispose(current_module^.mainsource);
+               current_module^.mainsource:=stringdup(hs);
+             end;
+{$endif ORDERSOURCES}
+           Message1(unit_u_ppu_source,hs+temp);
+{$ifdef ORDERSOURCES}
+           is_main:=false;
+{$endif ORDERSOURCES}
+         end;
+{$ifndef ORDERSOURCES}
+      { main source is always the last }
+        stringdispose(current_module^.mainsource);
+        current_module^.mainsource:=stringdup(hs);
+
+        { the indexing is corrected here PM }
+        current_module^.sourcefiles^.inverse_register_indexes;
+{$endif ORDERSOURCES}
+      { check if we want to rebuild every unit, only if the sources are
+        available }
+        if do_build and current_module^.sources_avail then
+          begin
+             current_module^.do_compile:=true;
+             current_module^.recompile_reason:=rr_build;
+          end;
+      end;
+
+
+    procedure readloadunit;
+      var
+        hs : string;
+        intfchecksum,
+        checksum : longint;
+        in_interface : boolean;
+      begin
+        while not current_ppu^.endofentry do
+         begin
+           hs:=current_ppu^.getstring;
+           checksum:=current_ppu^.getlongint;
+           intfchecksum:=current_ppu^.getlongint;
+           in_interface:=(current_ppu^.getbyte<>0);
+           current_module^.used_units.concat(new(pused_unit,init_to_load(hs,checksum,intfchecksum,in_interface)));
+         end;
+      end;
+
+
+    procedure readlinkcontainer(var p:tlinkcontainer);
+      var
+        s : string;
+        m : longint;
+      begin
+        while not current_ppu^.endofentry do
+         begin
+           s:=current_ppu^.getstring;
+           m:=current_ppu^.getlongint;
+           p.insert(s,m);
+         end;
+      end;
+
+
+    procedure load_interface;
+      var
+        b : byte;
+        newmodulename : string;
+      begin
+       { read interface part }
+         repeat
+           b:=current_ppu^.readentry;
+           case b of
+             ibmodulename :
+               begin
+                 newmodulename:=current_ppu^.getstring;
+                 if upper(newmodulename)<>current_module^.modulename^ then
+                   Message2(unit_f_unit_name_error,current_module^.realmodulename^,newmodulename);
+                 stringdispose(current_module^.modulename);
+                 stringdispose(current_module^.realmodulename);
+                 current_module^.modulename:=stringdup(upper(newmodulename));
+                 current_module^.realmodulename:=stringdup(newmodulename);
+               end;
+             ibsourcefiles :
+               readsourcefiles;
+             ibusedmacros :
+               readusedmacros;
+             ibloadunit :
+               readloadunit;
+             iblinkunitofiles :
+               readlinkcontainer(current_module^.LinkUnitOFiles);
+             iblinkunitstaticlibs :
+               readlinkcontainer(current_module^.LinkUnitStaticLibs);
+             iblinkunitsharedlibs :
+               readlinkcontainer(current_module^.LinkUnitSharedLibs);
+             iblinkotherofiles :
+               readlinkcontainer(current_module^.LinkotherOFiles);
+             iblinkotherstaticlibs :
+               readlinkcontainer(current_module^.LinkotherStaticLibs);
+             iblinkothersharedlibs :
+               readlinkcontainer(current_module^.LinkotherSharedLibs);
+             ibendinterface :
+               break;
+           else
+             Message1(unit_f_ppu_invalid_entry,tostr(b));
+           end;
+         until false;
+      end;
+
+{
+  $Log$
+  Revision 1.7  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.6  2000/10/31 22:02:52  peter
+    * symtable splitted, no real code changes
+
+  Revision 1.5  2000/10/15 07:47:53  peter
+    * unit names and procedure names are stored mixed case
+
+  Revision 1.4  2000/09/24 21:33:47  peter
+    * message updates merges
+
+  Revision 1.3  2000/09/21 20:56:19  pierre
+   * fix for bugs 1084/1128 (merged)
+
+  Revision 1.2  2000/07/13 11:32:49  michael
+  + removed logs
+
+}

+ 19 - 1
compiler/symppu.pas

@@ -38,6 +38,7 @@ interface
     procedure writestring(const s:string);
     procedure writestring(const s:string);
     procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
     procedure writenormalset(var s); {You cannot pass an array[0..31] of byte!}
     procedure writesmallset(var s);
     procedure writesmallset(var s);
+    procedure writeguid(var g: tguid);
     procedure writeposinfo(const p:tfileposinfo);
     procedure writeposinfo(const p:tfileposinfo);
     procedure writederef(p : psymtableentry);
     procedure writederef(p : psymtableentry);
 
 
@@ -48,6 +49,7 @@ interface
     function readstring : string;
     function readstring : string;
     procedure readnormalset(var s);   {You cannot pass an array [0..31] of byte.}
     procedure readnormalset(var s);   {You cannot pass an array [0..31] of byte.}
     procedure readsmallset(var s);
     procedure readsmallset(var s);
+    procedure readguid(var g: tguid);
     procedure readposinfo(var p:tfileposinfo);
     procedure readposinfo(var p:tfileposinfo);
     function readderef : psymtableentry;
     function readderef : psymtableentry;
 
 
@@ -57,6 +59,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
+       globals,
        symconst,
        symconst,
        verbose,
        verbose,
        finput,scanner,
        finput,scanner,
@@ -122,6 +125,11 @@ implementation
       end;
       end;
 
 
 
 
+    procedure writeguid(var g: tguid);
+      begin
+        current_ppu^.putdata(g,sizeof(g));
+      end;
+
     procedure writederef(p : psymtableentry);
     procedure writederef(p : psymtableentry);
       begin
       begin
         if p=nil then
         if p=nil then
@@ -277,6 +285,13 @@ implementation
       end;
       end;
 
 
 
 
+    procedure readguid(var g: tguid);
+      begin
+        current_ppu^.getdata(g,sizeof(g));
+        if current_ppu^.error then
+         Message(unit_f_ppu_read_error);
+      end;
+
     procedure readposinfo(var p:tfileposinfo);
     procedure readposinfo(var p:tfileposinfo);
       begin
       begin
         p.fileindex:=current_ppu^.getword;
         p.fileindex:=current_ppu^.getword;
@@ -322,7 +337,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2000-10-31 22:02:52  peter
+  Revision 1.2  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.1  2000/10/31 22:02:52  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
 }
 }

+ 2260 - 0
compiler/symsym.inc

@@ -0,0 +1,2260 @@
+{
+    $Id$
+    Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
+
+    Implementation for the symbols types of the symtable
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ ****************************************************************************
+}
+
+{****************************************************************************
+                          TSYM (base for all symtypes)
+****************************************************************************}
+
+    constructor tsym.init(const n : string);
+      begin
+         if n[1]='$' then
+          inherited initname(copy(n,2,255))
+         else
+          inherited initname(upper(n));
+         _realname:=stringdup(n);
+         typ:=abstractsym;
+         symoptions:=current_object_option;
+{$ifdef GDB}
+         isstabwritten := false;
+{$endif GDB}
+         fileinfo:=tokenpos;
+         defref:=nil;
+         refs:=0;
+         lastwritten:=nil;
+         refcount:=0;
+         if (cs_browser in aktmoduleswitches) and make_ref then
+          begin
+            defref:=new(pref,init(defref,@tokenpos));
+            inc(refcount);
+          end;
+         lastref:=defref;
+      end;
+
+
+    constructor tsym.load;
+      begin
+         inherited init;
+         indexnr:=readword;
+         _realname:=stringdup(readstring);
+         if _realname^[1]='$' then
+          setname(copy(_realname^,2,255))
+         else
+          setname(upper(_realname^));
+         typ:=abstractsym;
+         readsmallset(symoptions,sizeof(symoptions));
+         readposinfo(fileinfo);
+         lastref:=nil;
+         defref:=nil;
+         refs:=0;
+         lastwritten:=nil;
+         refcount:=0;
+{$ifdef GDB}
+         isstabwritten := false;
+{$endif GDB}
+      end;
+
+
+    procedure tsym.load_references;
+      var
+        pos : tfileposinfo;
+        move_last : boolean;
+      begin
+        move_last:=lastwritten=lastref;
+        while (not current_ppu^.endofentry) do
+         begin
+           readposinfo(pos);
+           inc(refcount);
+           lastref:=new(pref,init(lastref,@pos));
+           lastref^.is_written:=true;
+           if refcount=1 then
+            defref:=lastref;
+         end;
+        if move_last then
+          lastwritten:=lastref;
+      end;
+
+    { big problem here :
+      wrong refs were written because of
+      interface parsing of other units PM
+      moduleindex must be checked !! }
+
+    function tsym.write_references : boolean;
+      var
+        ref   : pref;
+        symref_written,move_last : boolean;
+      begin
+        write_references:=false;
+        if lastwritten=lastref then
+          exit;
+      { should we update lastref }
+        move_last:=true;
+        symref_written:=false;
+      { write symbol refs }
+        if assigned(lastwritten) then
+          ref:=lastwritten
+        else
+          ref:=defref;
+        while assigned(ref) do
+         begin
+           if ref^.moduleindex=current_module^.unit_index then
+             begin
+              { write address to this symbol }
+                if not symref_written then
+                  begin
+                     writesymref(@self);
+                     symref_written:=true;
+                  end;
+                writeposinfo(ref^.posinfo);
+                ref^.is_written:=true;
+                if move_last then
+                  lastwritten:=ref;
+             end
+           else if not ref^.is_written then
+             move_last:=false
+           else if move_last then
+             lastwritten:=ref;
+           ref:=ref^.nextref;
+         end;
+        if symref_written then
+          current_ppu^.writeentry(ibsymref);
+        write_references:=symref_written;
+      end;
+
+
+{$ifdef BrowserLog}
+    procedure tsym.add_to_browserlog;
+      begin
+        if assigned(defref) then
+         begin
+           browserlog.AddLog('***'+name+'***');
+           browserlog.AddLogRefs(defref);
+         end;
+      end;
+{$endif BrowserLog}
+
+
+    destructor tsym.done;
+      begin
+        if assigned(defref) then
+         begin
+           defref^.freechain;
+           dispose(defref,done);
+         end;
+        stringdispose(_realname);
+        inherited done;
+      end;
+
+
+    procedure tsym.write;
+      begin
+         writeword(indexnr);
+         writestring(_realname^);
+         writesmallset(symoptions,sizeof(symoptions));
+         writeposinfo(fileinfo);
+      end;
+
+
+    procedure tsym.prederef;
+      begin
+      end;
+
+
+    procedure tsym.deref;
+      begin
+      end;
+
+
+    function tsym.realname : string;
+      begin
+        if assigned(_realname) then
+         realname:=_realname^
+        else
+         realname:=name;
+      end;
+
+
+    function tsym.mangledname : string;
+      begin
+         mangledname:=name;
+      end;
+
+
+    { for most symbol types there is nothing to do at all }
+    procedure tsym.insert_in_data;
+      begin
+      end;
+
+
+{$ifdef GDB}
+    function tsym.stabstring : pchar;
+
+      begin
+         stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
+           tostr(fileinfo.line)+',0');
+      end;
+
+    procedure tsym.concatstabto(asmlist : paasmoutput);
+
+    var stab_str : pchar;
+      begin
+         if not isstabwritten then
+           begin
+              stab_str := stabstring;
+              { count_dbx(stab_str); moved to GDB.PAS }
+              asmlist^.concat(new(pai_stabs,init(stab_str)));
+              isstabwritten:=true;
+          end;
+    end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                 TLABELSYM
+****************************************************************************}
+
+    constructor tlabelsym.init(const n : string; l : pasmlabel);
+
+      begin
+         inherited init(n);
+         typ:=labelsym;
+         lab:=l;
+         used:=false;
+         defined:=false;
+         code:=nil;
+      end;
+
+    constructor tlabelsym.load;
+
+      begin
+         tsym.load;
+         typ:=labelsym;
+         { this is all dummy
+           it is only used for local browsing }
+         lab:=nil;
+         code:=nil;
+         used:=false;
+         defined:=true;
+      end;
+
+    destructor tlabelsym.done;
+
+      begin
+         inherited done;
+      end;
+
+
+    function tlabelsym.mangledname : string;
+      begin
+         mangledname:=lab^.name;
+      end;
+
+
+    procedure tlabelsym.write;
+      begin
+         if owner^.symtabletype in [unitsymtable,globalsymtable] then
+           Message(sym_e_ill_label_decl)
+         else
+           begin
+              tsym.write;
+              current_ppu^.writeentry(iblabelsym);
+           end;
+      end;
+
+
+{****************************************************************************
+                                  TUNITSYM
+****************************************************************************}
+
+    constructor tunitsym.init(const n : string;ref : punitsymtable);
+      var
+        old_make_ref : boolean;
+      begin
+         old_make_ref:=make_ref;
+         make_ref:=false;
+         inherited init(n);
+         make_ref:=old_make_ref;
+         typ:=unitsym;
+         unitsymtable:=ref;
+         prevsym:=ref^.unitsym;
+         ref^.unitsym:=@self;
+         refs:=0;
+      end;
+
+    constructor tunitsym.load;
+
+      begin
+         tsym.load;
+         typ:=unitsym;
+         unitsymtable:=punitsymtable(current_module^.globalsymtable);
+         prevsym:=nil;
+      end;
+
+    { we need to remove it from the prevsym chain ! }
+
+    procedure tunitsym.restoreunitsym;
+      var pus,ppus : punitsym;
+      begin
+         if assigned(unitsymtable) then
+           begin
+             ppus:=nil;
+             pus:=unitsymtable^.unitsym;
+             if pus=@self then
+               unitsymtable^.unitsym:=prevsym
+             else while assigned(pus) do
+               begin
+                  if pus=@self then
+                    begin
+                       ppus^.prevsym:=prevsym;
+                       break;
+                    end
+                  else
+                    begin
+                       ppus:=pus;
+                       pus:=ppus^.prevsym;
+                    end;
+               end;
+           end;
+         prevsym:=nil;
+      end;
+
+    destructor tunitsym.done;
+      begin
+         restoreunitsym;
+         inherited done;
+      end;
+
+    procedure tunitsym.write;
+      begin
+         tsym.write;
+         current_ppu^.writeentry(ibunitsym);
+      end;
+
+{$ifdef GDB}
+    procedure tunitsym.concatstabto(asmlist : paasmoutput);
+      begin
+      {Nothing to write to stabs !}
+      end;
+{$endif GDB}
+
+{****************************************************************************
+                                  TPROCSYM
+****************************************************************************}
+
+    constructor tprocsym.init(const n : string);
+
+      begin
+         tsym.init(n);
+         typ:=procsym;
+         definition:=nil;
+         owner:=nil;
+         is_global := false;
+      end;
+
+    constructor tprocsym.load;
+
+      begin
+         tsym.load;
+         typ:=procsym;
+         definition:=pprocdef(readdefref);
+         is_global := false;
+      end;
+
+    destructor tprocsym.done;
+
+      begin
+         { don't check if errors !! }
+         if Errorcount=0 then
+           check_forward;
+         tsym.done;
+      end;
+
+    function tprocsym.mangledname : string;
+
+      begin
+         mangledname:=definition^.mangledname;
+      end;
+
+
+    function tprocsym.declarationstr(p : pprocdef):string;
+      begin
+        declarationstr:=realname+p^.demangled_paras;
+      end;
+
+
+    procedure tprocsym.write_parameter_lists(skipdef:pprocdef);
+      var
+         p : pprocdef;
+      begin
+         p:=definition;
+         while assigned(p) do
+           begin
+              if p<>skipdef then
+                MessagePos1(p^.fileinfo,sym_b_param_list,name+p^.demangled_paras);
+              p:=p^.nextoverloaded;
+           end;
+      end;
+
+
+    procedure tprocsym.check_forward;
+      var
+         pd : pprocdef;
+      begin
+         pd:=definition;
+         while assigned(pd) do
+           begin
+              if pd^.forwarddef then
+                begin
+                   if assigned(pd^._class) then
+                     MessagePos1(fileinfo,sym_e_forward_not_resolved,pd^._class^.objname^+'.'+declarationstr(pd))
+                   else
+                     MessagePos1(fileinfo,sym_e_forward_not_resolved,declarationstr(pd));
+                   { Turn futher error messages off }
+                   pd^.forwarddef:=false;
+                end;
+              pd:=pd^.nextoverloaded;
+              { do not check defs of operators in other units }
+              if assigned(pd) and (pd^.procsym<>@self) then
+                pd:=nil;
+           end;
+      end;
+
+
+    procedure tprocsym.deref;
+{$ifdef DONOTCHAINOPERATORS}
+      var
+        t    : ttoken;
+        last,pd : pprocdef;
+{$endif DONOTCHAINOPERATORS}
+      begin
+         resolvedef(pdef(definition));
+{$ifdef DONOTCHAINOPERATORS}
+         if (definition^.proctypeoption=potype_operator) then
+           begin
+              last:=definition;
+              while assigned(last^.nextoverloaded) do
+                last:=last^.nextoverloaded;
+              for t:=first_overloaded to last_overloaded do
+              if (name=overloaded_names[t]) then
+                begin
+                   if assigned(overloaded_operators[t]) then
+                     begin
+                       pd:=overloaded_operators[t]^.definition;
+                       { test if not already in list, bug report by KC Wong PM }
+                       while assigned(pd) do
+                         if pd=last then
+                           break
+                         else
+                           pd:=pd^.nextoverloaded;
+                       if pd=last then
+                         break;
+                       last^.nextoverloaded:=overloaded_operators[t]^.definition;
+                     end;
+                   overloaded_operators[t]:=@self;
+                   break;
+                end;
+           end;
+{$endif DONOTCHAINOPERATORS}
+      end;
+
+    procedure tprocsym.order_overloaded;
+      var firstdef,currdef,lastdef,nextopdef : pprocdef;
+      begin
+         if not assigned(definition) then
+           exit;
+         firstdef:=definition;
+         currdef:=definition;
+         while assigned(currdef) and (currdef^.owner=firstdef^.owner) do
+           begin
+             currdef^.count:=false;
+             currdef:=currdef^.nextoverloaded;
+           end;
+         nextopdef:=currdef;
+         definition:=definition^.nextoverloaded;
+         firstdef^.nextoverloaded:=nil;
+         while (definition<>nextopdef) do
+           begin
+             currdef:=firstdef;
+             lastdef:=definition;
+             definition:=definition^.nextoverloaded;
+             if lastdef^.mangledname<firstdef^.mangledname then
+               begin
+                 lastdef^.nextoverloaded:=firstdef;
+                 firstdef:=lastdef;
+               end
+             else
+               begin
+                 while assigned(currdef^.nextoverloaded) and
+                    (lastdef^.mangledname>currdef^.nextoverloaded^.mangledname) do
+                   currdef:=currdef^.nextoverloaded;
+                 lastdef^.nextoverloaded:=currdef^.nextoverloaded;
+                 currdef^.nextoverloaded:=lastdef;
+               end;
+           end;
+         definition:=firstdef;
+         currdef:=definition;
+         while assigned(currdef) do
+           begin
+             currdef^.count:=true;
+             lastdef:=currdef;
+             currdef:=currdef^.nextoverloaded;
+           end;
+         lastdef^.nextoverloaded:=nextopdef;
+      end;
+
+    procedure tprocsym.write;
+      begin
+         tsym.write;
+         writedefref(pdef(definition));
+         current_ppu^.writeentry(ibprocsym);
+      end;
+
+
+    procedure tprocsym.load_references;
+      (*var
+        prdef,prdef2 : pprocdef;
+        b : byte; *)
+      begin
+         inherited load_references;
+         (*prdef:=definition;
+           done in tsymtable.load_browser (PM)
+         { take care about operators !!  }
+         if (current_module^.flags and uf_has_browser) <>0 then
+           while assigned(prdef) and (prdef^.owner=definition^.owner) do
+             begin
+                b:=current_ppu^.readentry;
+                if b<>ibdefref then
+                  Message(unit_f_ppu_read_error);
+                prdef2:=pprocdef(readdefref);
+                resolvedef(prdef2);
+                if prdef<>prdef2 then
+                  Message(unit_f_ppu_read_error);
+                prdef^.load_references;
+                prdef:=prdef^.nextoverloaded;
+             end; *)
+      end;
+
+    function tprocsym.write_references : boolean;
+      var
+        prdef : pprocdef;
+      begin
+         write_references:=false;
+         if not inherited write_references then
+           exit;
+         write_references:=true;
+         prdef:=definition;
+         while assigned(prdef) and (prdef^.owner=definition^.owner) do
+          begin
+            prdef^.write_references;
+            prdef:=prdef^.nextoverloaded;
+          end;
+      end;
+
+
+{$ifdef BrowserLog}
+    procedure tprocsym.add_to_browserlog;
+      var
+        prdef : pprocdef;
+      begin
+         inherited add_to_browserlog;
+         prdef:=definition;
+         while assigned(prdef) do
+           begin
+              pprocdef(prdef)^.add_to_browserlog;
+              prdef:=pprocdef(prdef)^.nextoverloaded;
+           end;
+      end;
+{$endif BrowserLog}
+
+
+{$ifdef GDB}
+    function tprocsym.stabstring : pchar;
+     Var RetType : Char;
+         Obj,Info : String;
+         stabsstr : string;
+         p : pchar;
+    begin
+      obj := name;
+      info := '';
+      if is_global then
+       RetType := 'F'
+      else
+       RetType := 'f';
+     if assigned(owner) then
+      begin
+        if (owner^.symtabletype = objectsymtable) then
+         obj := owner^.name^+'__'+name;
+        { this code was correct only as long as the local symboltable
+          of the parent had the same name as the function
+          but this is no true anymore !! PM
+        if (owner^.symtabletype=localsymtable) and assigned(owner^.name) then
+         info := ','+name+','+owner^.name^;  }
+        if (owner^.symtabletype=localsymtable) and assigned(owner^.defowner) and
+           assigned(pprocdef(owner^.defowner)^.procsym) then
+          info := ','+name+','+pprocdef(owner^.defowner)^.procsym^.name;
+      end;
+     stabsstr:=definition^.mangledname;
+     getmem(p,length(stabsstr)+255);
+     strpcopy(p,'"'+obj+':'+RetType
+           +definition^.rettype.def^.numberstring+info+'",'+tostr(n_function)
+           +',0,'+
+           tostr(aktfilepos.line)
+           +',');
+     strpcopy(strend(p),stabsstr);
+     stabstring:=strnew(p);
+     freemem(p,length(stabsstr)+255);
+    end;
+
+    procedure tprocsym.concatstabto(asmlist : paasmoutput);
+    begin
+      if (pocall_internproc in definition^.proccalloptions) then exit;
+      if not isstabwritten then
+        asmlist^.concat(new(pai_stabs,init(stabstring)));
+      isstabwritten := true;
+      if assigned(definition^.parast) then
+        definition^.parast^.concatstabto(asmlist);
+      { local type defs and vars should not be written
+        inside the main proc stab }
+      if assigned(definition^.localst) and
+         (lexlevel>main_program_level) then
+        definition^.localst^.concatstabto(asmlist);
+      definition^.is_def_stab_written := written;
+    end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TERRORSYM
+****************************************************************************}
+
+    constructor terrorsym.init;
+      begin
+        inherited init('');
+        typ:=errorsym;
+      end;
+
+{****************************************************************************
+                                TPROPERTYSYM
+****************************************************************************}
+
+    constructor tpropertysym.init(const n : string);
+      begin
+         inherited init(n);
+         typ:=propertysym;
+         propoptions:=[];
+         index:=0;
+         default:=0;
+         proptype.reset;
+         indextype.reset;
+         new(readaccess,init);
+         new(writeaccess,init);
+         new(storedaccess,init);
+      end;
+
+
+    constructor tpropertysym.load;
+      begin
+         inherited load;
+         typ:=propertysym;
+         readsmallset(propoptions,sizeof(propoptions));
+         if (ppo_is_override in propoptions) then
+          begin
+            propoverriden:=ppropertysym(readsymref);
+            { we need to have these objects initialized }
+            new(readaccess,init);
+            new(writeaccess,init);
+            new(storedaccess,init);
+          end
+         else
+          begin
+            proptype.load;
+            index:=readlong;
+            default:=readlong;
+            indextype.load;
+            new(readaccess,load);
+            new(writeaccess,load);
+            new(storedaccess,load);
+          end;
+      end;
+
+
+    destructor tpropertysym.done;
+      begin
+         dispose(readaccess,done);
+         dispose(writeaccess,done);
+         dispose(storedaccess,done);
+         inherited done;
+      end;
+
+
+    procedure tpropertysym.deref;
+      begin
+        if (ppo_is_override in propoptions) then
+         begin
+           resolvesym(psym(propoverriden));
+           dooverride(propoverriden);
+         end
+        else
+         begin
+           proptype.resolve;
+           indextype.resolve;
+           readaccess^.resolve;
+           writeaccess^.resolve;
+           storedaccess^.resolve;
+         end;
+      end;
+
+
+    function tpropertysym.getsize : longint;
+      begin
+         getsize:=0;
+      end;
+
+
+    procedure tpropertysym.write;
+      begin
+        tsym.write;
+        writesmallset(propoptions,sizeof(propoptions));
+        if (ppo_is_override in propoptions) then
+         writesymref(propoverriden)
+        else
+         begin
+           proptype.write;
+           writelong(index);
+           writelong(default);
+           indextype.write;
+           readaccess^.write;
+           writeaccess^.write;
+           storedaccess^.write;
+         end;
+        current_ppu^.writeentry(ibpropertysym);
+      end;
+
+
+    procedure tpropertysym.dooverride(overriden:ppropertysym);
+      begin
+        propoverriden:=overriden;
+        proptype:=overriden^.proptype;
+        propoptions:=overriden^.propoptions+[ppo_is_override];
+        index:=overriden^.index;
+        default:=overriden^.default;
+        indextype:=overriden^.indextype;
+        readaccess^.clear;
+        readaccess:=overriden^.readaccess^.getcopy;
+        writeaccess^.clear;
+        writeaccess:=overriden^.writeaccess^.getcopy;
+        storedaccess^.clear;
+        storedaccess:=overriden^.storedaccess^.getcopy;
+      end;
+
+
+{$ifdef GDB}
+    function tpropertysym.stabstring : pchar;
+      begin
+         { !!!! don't know how to handle }
+         stabstring:=strpnew('');
+      end;
+
+    procedure tpropertysym.concatstabto(asmlist : paasmoutput);
+      begin
+         { !!!! don't know how to handle }
+      end;
+{$endif GDB}
+
+{****************************************************************************
+                                  TFUNCRETSYM
+****************************************************************************}
+
+    constructor tfuncretsym.init(const n : string;approcinfo : pointer{pprocinfo});
+
+      begin
+         tsym.init(n);
+         typ:=funcretsym;
+         funcretprocinfo:=approcinfo;
+         rettype:=pprocinfo(approcinfo)^.returntype;
+         { address valid for ret in param only }
+         { otherwise set by insert             }
+         address:=pprocinfo(approcinfo)^.return_offset;
+      end;
+
+    constructor tfuncretsym.load;
+      begin
+         tsym.load;
+         rettype.load;
+         address:=readlong;
+         funcretprocinfo:=nil;
+         typ:=funcretsym;
+      end;
+
+    destructor tfuncretsym.done;
+      begin
+        inherited done;
+      end;
+
+    procedure tfuncretsym.write;
+      begin
+         tsym.write;
+         rettype.write;
+         writelong(address);
+         current_ppu^.writeentry(ibfuncretsym);
+      end;
+
+    procedure tfuncretsym.deref;
+      begin
+         rettype.resolve;
+      end;
+
+{$ifdef GDB}
+    procedure tfuncretsym.concatstabto(asmlist : paasmoutput);
+      begin
+        { Nothing to do here, it is done in genexitcode  }
+      end;
+{$endif GDB}
+
+    procedure tfuncretsym.insert_in_data;
+      var
+        l : longint;
+      begin
+        { if retoffset is already set then reuse it, this is needed
+          when inserting the result variable }
+        if procinfo^.return_offset<>0 then
+         address:=procinfo^.return_offset
+        else
+         begin
+           { allocate space in local if ret in acc or in fpu }
+           if ret_in_acc(procinfo^.returntype.def) or (procinfo^.returntype.def^.deftype=floatdef) then
+            begin
+              l:=rettype.def^.size;
+              inc(owner^.datasize,l);
+{$ifdef m68k}
+              { word alignment required for motorola }
+              if (l=1) then
+               inc(owner^.datasize,1)
+              else
+{$endif}
+              if (l>=4) and ((owner^.datasize and 3)<>0) then
+                inc(owner^.datasize,4-(owner^.datasize and 3))
+              else if (l>=2) and ((owner^.datasize and 1)<>0) then
+                inc(owner^.datasize,2-(owner^.datasize and 1));
+              address:=owner^.datasize;
+              procinfo^.return_offset:=-owner^.datasize;
+            end;
+         end;
+      end;
+
+
+{****************************************************************************
+                                  TABSOLUTESYM
+****************************************************************************}
+
+    constructor tabsolutesym.init(const n : string;const tt : ttype);
+      begin
+        inherited init(n,tt);
+        typ:=absolutesym;
+      end;
+
+
+    constructor tabsolutesym.initdef(const n : string;p : pdef);
+      var
+        t : ttype;
+      begin
+        t.setdef(p);
+        tabsolutesym.init(n,t);
+      end;
+
+
+    constructor tabsolutesym.load;
+      begin
+         tvarsym.load;
+         typ:=absolutesym;
+         ref:=nil;
+         address:=0;
+         asmname:=nil;
+         abstyp:=absolutetyp(readbyte);
+         absseg:=false;
+         case abstyp of
+           tovar :
+             begin
+               asmname:=stringdup(readstring);
+               ref:=srsym;
+             end;
+           toasm :
+             asmname:=stringdup(readstring);
+           toaddr :
+             begin
+               address:=readlong;
+               absseg:=boolean(readbyte);
+             end;
+         end;
+      end;
+
+
+    procedure tabsolutesym.write;
+      var
+        hvo : tvaroptions;
+      begin
+         { Note: This needs to write everything of tvarsym.write }
+         tsym.write;
+         writebyte(byte(varspez));
+         if read_member then
+           writelong(address);
+         { write only definition or definitionsym }
+         vartype.write;
+         hvo:=varoptions-[vo_regable];
+         writesmallset(hvo,sizeof(hvo));
+         writebyte(byte(abstyp));
+         case abstyp of
+           tovar :
+             writestring(ref^.name);
+           toasm :
+             writestring(asmname^);
+           toaddr :
+             begin
+               writelong(address);
+               writebyte(byte(absseg));
+             end;
+         end;
+        current_ppu^.writeentry(ibabsolutesym);
+      end;
+
+
+    procedure tabsolutesym.deref;
+      begin
+         tvarsym.deref;
+         if (abstyp=tovar) and (asmname<>nil) then
+           begin
+              { search previous loaded symtables }
+              getsym(asmname^,false);
+              if not(assigned(srsym)) then
+                getsymonlyin(owner,asmname^);
+              if not(assigned(srsym)) then
+                srsym:=generrorsym;
+              ref:=srsym;
+              stringdispose(asmname);
+           end;
+      end;
+
+
+    function tabsolutesym.mangledname : string;
+      begin
+         case abstyp of
+           tovar :
+             mangledname:=ref^.mangledname;
+           toasm :
+             mangledname:=asmname^;
+           toaddr :
+             mangledname:='$'+tostr(address);
+         else
+           internalerror(10002);
+         end;
+      end;
+
+
+    procedure tabsolutesym.insert_in_data;
+      begin
+      end;
+
+
+{$ifdef GDB}
+    procedure tabsolutesym.concatstabto(asmlist : paasmoutput);
+      begin
+      { I don't know how to handle this !! }
+      end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TVARSYM
+****************************************************************************}
+
+    constructor tvarsym.init(const n : string;const tt : ttype);
+      begin
+         tsym.init(n);
+         typ:=varsym;
+         vartype:=tt;
+         _mangledname:=nil;
+         varspez:=vs_value;
+         address:=0;
+         localvarsym:=nil;
+         refs:=0;
+         varstate:=vs_used;
+         varoptions:=[];
+         { can we load the value into a register ? }
+         if tt.def^.is_intregable then
+           include(varoptions,vo_regable)
+         else
+           exclude(varoptions,vo_regable);
+
+         if tt.def^.is_fpuregable then
+           include(varoptions,vo_fpuregable)
+         else
+           exclude(varoptions,vo_fpuregable);
+         reg:=R_NO;
+      end;
+
+
+    constructor tvarsym.init_dll(const n : string;const tt : ttype);
+      begin
+         tvarsym.init(n,tt);
+         include(varoptions,vo_is_dll_var);
+      end;
+
+
+    constructor tvarsym.init_C(const n,mangled : string;const tt : ttype);
+      begin
+         tvarsym.init(n,tt);
+         include(varoptions,vo_is_C_var);
+         setmangledname(mangled);
+      end;
+
+
+    constructor tvarsym.initdef(const n : string;p : pdef);
+      var
+        t : ttype;
+      begin
+        t.setdef(p);
+        tvarsym.init(n,t);
+      end;
+
+
+    constructor tvarsym.load;
+      begin
+         tsym.load;
+         typ:=varsym;
+         _mangledname:=nil;
+         reg:=R_NO;
+         refs := 0;
+         varstate:=vs_used;
+         varspez:=tvarspez(readbyte);
+         if read_member then
+           address:=readlong
+         else
+           address:=0;
+         localvarsym:=nil;
+         vartype.load;
+         readsmallset(varoptions,sizeof(varoptions));
+         if (vo_is_C_var in varoptions) then
+           setmangledname(readstring);
+      end;
+
+
+    destructor tvarsym.done;
+      begin
+         strdispose(_mangledname);
+         inherited done;
+      end;
+
+
+    procedure tvarsym.deref;
+      begin
+        vartype.resolve;
+      end;
+
+
+    procedure tvarsym.write;
+      var
+        hvo : tvaroptions;
+      begin
+         tsym.write;
+         writebyte(byte(varspez));
+         if read_member then
+          writelong(address);
+         vartype.write;
+         { symbols which are load are never candidates for a register,
+           turn off the regable }
+         hvo:=varoptions-[vo_regable];
+         writesmallset(hvo,sizeof(hvo));
+         if (vo_is_C_var in varoptions) then
+           writestring(mangledname);
+         current_ppu^.writeentry(ibvarsym);
+      end;
+
+
+    procedure tvarsym.setmangledname(const s : string);
+      begin
+        _mangledname:=strpnew(s);
+      end;
+
+
+    function tvarsym.mangledname : string;
+      var
+        prefix : string;
+      begin
+         if assigned(_mangledname) then
+           begin
+              mangledname:=strpas(_mangledname);
+              exit;
+           end;
+         case owner^.symtabletype of
+           staticsymtable :
+             if (cs_create_smart in aktmoduleswitches) then
+               prefix:='_'+owner^.name^+'$$$_'
+             else
+               prefix:='_';
+           unitsymtable,
+           globalsymtable :
+             prefix:=
+              'U_'+owner^.name^+'_';
+           else
+             Message(sym_e_invalid_call_tvarsymmangledname);
+         end;
+         mangledname:=prefix+name;
+      end;
+
+
+    function tvarsym.getsize : longint;
+      begin
+        if assigned(vartype.def) then
+          getsize:=vartype.def^.size
+        else
+          getsize:=0;
+      end;
+
+
+    function tvarsym.getvaluesize : longint;
+      begin
+        if assigned(vartype.def) and
+           (varspez=vs_value) and
+           ((vartype.def^.deftype<>arraydef) or
+            (Parraydef(vartype.def)^.highrange>=Parraydef(vartype.def)^.lowrange)) then
+          getvaluesize:=vartype.def^.size
+        else
+          getvaluesize:=0;
+      end;
+
+
+    function tvarsym.getpushsize : longint;
+      begin
+         if assigned(vartype.def) then
+           begin
+              case varspez of
+                vs_out,
+                vs_var :
+                  getpushsize:=target_os.size_of_pointer;
+                vs_value,
+                vs_const :
+                  begin
+                      if push_addr_param(vartype.def) then
+                        getpushsize:=target_os.size_of_pointer
+                      else
+                        getpushsize:=vartype.def^.size;
+                  end;
+              end;
+           end
+         else
+           getpushsize:=0;
+      end;
+
+
+    function  data_align(length : longint) : longint;
+      begin
+         (* this is useless under go32v2 at least
+         because the section are only align to dword
+         if length>8 then
+           data_align:=16
+         else if length>4 then
+           data_align:=8
+         else *)
+         if length>2 then
+           data_align:=4
+         else
+          if length>1 then
+           data_align:=2
+         else
+           data_align:=1;
+      end;
+
+
+    procedure tvarsym.insert_in_data;
+      var
+         varalign,
+         l,ali,modulo : longint;
+         storefilepos : tfileposinfo;
+      begin
+        if (vo_is_external in varoptions) then
+          exit;
+        { handle static variables of objects especially }
+        if read_member and (owner^.symtabletype=objectsymtable) and
+           (sp_static in symoptions) then
+         begin
+            { the data filed is generated in parser.pas
+              with a tobject_FIELDNAME variable }
+            { this symbol can't be loaded to a register }
+            exclude(varoptions,vo_regable);
+            exclude(varoptions,vo_fpuregable);
+         end
+        else
+         if not(read_member) then
+          begin
+             { made problems with parameters etc. ! (FK) }
+             {  check for instance of an abstract object or class }
+             {
+             if (pvarsym(sym)^.definition^.deftype=objectdef) and
+               (oo_is_abstract in pobjectdef(pvarsym(sym)^.definition)^.options) then
+               Message(sym_e_no_instance_of_abstract_object);
+             }
+             storefilepos:=aktfilepos;
+             aktfilepos:=tokenpos;
+             if (vo_is_thread_var in varoptions) then
+               l:=4
+             else
+               l:=getvaluesize;
+             case owner^.symtabletype of
+               stt_exceptsymtable:
+                 { can contain only one symbol, address calculated later }
+                 ;
+               localsymtable :
+                 begin
+                   varstate:=vs_declared;
+                   modulo:=owner^.datasize and 3;
+{$ifdef m68k}
+                 { word alignment required for motorola }
+                   if (l=1) then
+                    l:=2
+                   else
+{$endif}
+{
+                   if (cs_optimize in aktglobalswitches) and
+                      (aktoptprocessor in [classp5,classp6]) and
+                      (l>=8) and ((owner^.datasize and 7)<>0) then
+                     inc(owner^.datasize,8-(owner^.datasize and 7))
+                   else
+}
+                     begin
+                        if (l>=4) and (modulo<>0) then
+                          inc(l,4-modulo)
+                        else
+                          if (l>=2) and ((modulo and 1)<>0) then
+                            inc(l,2-(modulo and 1));
+                     end;
+                   inc(owner^.datasize,l);
+                   address:=owner^.datasize;
+                 end;
+               staticsymtable :
+                 begin
+                   { enable unitialized warning for local symbols }
+                   varstate:=vs_declared;
+                   if (cs_create_smart in aktmoduleswitches) then
+                     bsssegment^.concat(new(pai_cut,init));
+                   ali:=data_align(l);
+                   if ali>1 then
+                     begin
+                        modulo:=owner^.datasize mod ali;
+                        if modulo>0 then
+                          inc(owner^.datasize,ali-modulo);
+                     end;
+{$ifdef GDB}
+                   if cs_debuginfo in aktmoduleswitches then
+                      concatstabto(bsssegment);
+{$endif GDB}
+
+                   if (cs_create_smart in aktmoduleswitches) or
+                      DLLSource or
+                      (vo_is_exported in varoptions) or
+                      (vo_is_C_var in varoptions) then
+                     bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)))
+                   else
+                     bsssegment^.concat(new(pai_datablock,init(mangledname,l)));
+                   { increase datasize }
+                   inc(owner^.datasize,l);
+                   { this symbol can't be loaded to a register }
+                   exclude(varoptions,vo_regable);
+                   exclude(varoptions,vo_fpuregable);
+                 end;
+               globalsymtable :
+                 begin
+                   if (cs_create_smart in aktmoduleswitches) then
+                     bsssegment^.concat(new(pai_cut,init));
+                   ali:=data_align(l);
+                   if ali>1 then
+                     begin
+                        modulo:=owner^.datasize mod ali;
+                        if modulo>0 then
+                          inc(owner^.datasize,ali-modulo);
+                     end;
+{$ifdef GDB}
+                   if cs_debuginfo in aktmoduleswitches then
+                     concatstabto(bsssegment);
+{$endif GDB}
+                   bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)));
+                   inc(owner^.datasize,l);
+                   { this symbol can't be loaded to a register }
+                   exclude(varoptions,vo_regable);
+                   exclude(varoptions,vo_fpuregable);
+                 end;
+               recordsymtable,
+               objectsymtable :
+                 begin
+                 { this symbol can't be loaded to a register }
+                   exclude(varoptions,vo_regable);
+                   exclude(varoptions,vo_fpuregable);
+                 { get the alignment size }
+                   if (aktpackrecords=packrecord_C) then
+                    begin
+                      varalign:=vartype.def^.alignment;
+                      if (varalign>4) and ((varalign mod 4)<>0) and
+                        (vartype.def^.deftype=arraydef) then
+                        begin
+                          Message1(sym_w_wrong_C_pack,vartype.def^.typename);
+                        end;
+                      if varalign=0 then
+                        varalign:=l;
+                      if (owner^.dataalignment<target_os.maxCrecordalignment) then
+                       begin
+                         if (varalign>16) and (owner^.dataalignment<32) then
+                          owner^.dataalignment:=32
+                         else if (varalign>12) and (owner^.dataalignment<16) then
+                          owner^.dataalignment:=16
+                         { 12 is needed for long double }
+                         else if (varalign>8) and (owner^.dataalignment<12) then
+                          owner^.dataalignment:=12
+                         else if (varalign>4) and (owner^.dataalignment<8) then
+                          owner^.dataalignment:=8
+                         else if (varalign>2) and (owner^.dataalignment<4) then
+                          owner^.dataalignment:=4
+                         else if (varalign>1) and (owner^.dataalignment<2) then
+                          owner^.dataalignment:=2;
+                       end;
+                      if owner^.dataalignment>target_os.maxCrecordalignment then
+                        owner^.dataalignment:=target_os.maxCrecordalignment;
+                    end
+                   else
+                    varalign:=vartype.def^.alignment;
+                   if varalign=0 then
+                     varalign:=l;
+                 { align record and object fields }
+                   if (varalign=1) or (owner^.dataalignment=1) then
+                    begin
+                      address:=owner^.datasize;
+                      inc(owner^.datasize,l)
+                    end
+                   else if (varalign=2) or (owner^.dataalignment=2) then
+                     begin
+                       owner^.datasize:=(owner^.datasize+1) and (not 1);
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l)
+                     end
+                   else if (varalign<=4) or (owner^.dataalignment=4) then
+                     begin
+                       owner^.datasize:=(owner^.datasize+3) and (not 3);
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l);
+                     end
+                   else if (varalign<=8) or (owner^.dataalignment=8) then
+                     begin
+                       owner^.datasize:=(owner^.datasize+7) and (not 7);
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l);
+                     end
+                         { 12 is needed for C long double support }
+                   else if (varalign<=12) and (owner^.dataalignment=12) then
+                     begin
+                       owner^.datasize:=((owner^.datasize+11) div 12) * 12;
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l);
+                     end
+                   else if (varalign<=16) or (owner^.dataalignment=16) then
+                     begin
+                       owner^.datasize:=(owner^.datasize+15) and (not 15);
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l);
+                     end
+                   else if (varalign<=32) or (owner^.dataalignment=32) then
+                     begin
+                       owner^.datasize:=(owner^.datasize+31) and (not 31);
+                       address:=owner^.datasize;
+                       inc(owner^.datasize,l);
+                     end
+                    else
+                     internalerror(1000022);
+                 end;
+               parasymtable :
+                 begin
+                   { here we need the size of a push instead of the
+                     size of the data }
+                   l:=getpushsize;
+                   varstate:=vs_assigned;
+                   address:=owner^.datasize;
+                   owner^.datasize:=align(owner^.datasize+l,target_os.stackalignment);
+                 end
+               else
+                 begin
+                     modulo:=owner^.datasize and 3;
+                     if (l>=4) and (modulo<>0) then
+                       inc(owner^.datasize,4-modulo)
+                     else
+                       if (l>=2) and ((modulo and 1)<>0) then
+                         inc(owner^.datasize);
+                   address:=owner^.datasize;
+                   inc(owner^.datasize,l);
+                 end;
+               end;
+             aktfilepos:=storefilepos;
+        end;
+      end;
+
+{$ifdef GDB}
+    function tvarsym.stabstring : pchar;
+     var
+       st : string;
+     begin
+       st:=vartype.def^.numberstring;
+       if (owner^.symtabletype = objectsymtable) and
+          (sp_static in symoptions) then
+         begin
+            if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
+{$ifndef Delphi}
+            stabstring := strpnew('"'+owner^.name^+'__'+name+':'+st+
+                     '",'+
+                     tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
+{$endif}
+         end
+       else if (owner^.symtabletype = globalsymtable) or
+          (owner^.symtabletype = unitsymtable) then
+         begin
+            { Here we used S instead of
+              because with G GDB doesn't look at the address field
+              but searches the same name or with a leading underscore
+              but these names don't exist in pascal !}
+            if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
+            stabstring := strpnew('"'+name+':'+st+'",'+
+                     tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
+         end
+       else if owner^.symtabletype = staticsymtable then
+         begin
+            stabstring := strpnew('"'+name+':S'+st+'",'+
+                  tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
+         end
+       else if (owner^.symtabletype in [parasymtable,inlineparasymtable]) then
+         begin
+            case varspez of
+               vs_out,
+               vs_var   : st := 'v'+st;
+               vs_value,
+               vs_const : if push_addr_param(vartype.def) then
+                            st := 'v'+st { should be 'i' but 'i' doesn't work }
+                          else
+                            st := 'p'+st;
+              end;
+            stabstring := strpnew('"'+name+':'+st+'",'+
+                  tostr(N_PSYM)+',0,'+tostr(fileinfo.line)+','+
+                  tostr(address+owner^.address_fixup));
+                  {offset to ebp => will not work if the framepointer is esp
+                  so some optimizing will make things harder to debug }
+         end
+       else if (owner^.symtabletype in [localsymtable,inlinelocalsymtable]) then
+   {$ifdef i386}
+         if reg<>R_NO then
+           begin
+              { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
+              { this is the register order for GDB}
+              stabstring:=strpnew('"'+name+':r'+st+'",'+
+                        tostr(N_RSYM)+',0,'+
+                        tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
+           end
+         else
+   {$endif i386}
+           { I don't know if this will work (PM) }
+           if (vo_is_C_var in varoptions) then
+            stabstring := strpnew('"'+name+':S'+st+'",'+
+                  tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname)
+           else
+           stabstring := strpnew('"'+name+':'+st+'",'+
+                  tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address-owner^.address_fixup))
+       else
+         stabstring := inherited stabstring;
+  end;
+
+    procedure tvarsym.concatstabto(asmlist : paasmoutput);
+{$ifdef i386}
+      var stab_str : pchar;
+{$endif i386}
+      begin
+         inherited concatstabto(asmlist);
+{$ifdef i386}
+      if (owner^.symtabletype=parasymtable) and
+         (reg<>R_NO) then
+           begin
+           { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
+           { this is the register order for GDB}
+              stab_str:=strpnew('"'+name+':r'
+                     +vartype.def^.numberstring+'",'+
+                     tostr(N_RSYM)+',0,'+
+                     tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
+              asmlist^.concat(new(pai_stabs,init(stab_str)));
+           end;
+{$endif i386}
+      end;
+{$endif GDB}
+
+
+{****************************************************************************
+                             TTYPEDCONSTSYM
+*****************************************************************************}
+
+    constructor ttypedconstsym.init(const n : string;p : pdef;really_const : boolean);
+      begin
+         tsym.init(n);
+         typ:=typedconstsym;
+         typedconsttype.setdef(p);
+         is_really_const:=really_const;
+         prefix:=stringdup(procprefix);
+      end;
+
+
+    constructor ttypedconstsym.inittype(const n : string;const tt : ttype;really_const : boolean);
+      begin
+         ttypedconstsym.init(n,nil,really_const);
+         typedconsttype:=tt;
+      end;
+
+
+    constructor ttypedconstsym.load;
+      begin
+         tsym.load;
+         typ:=typedconstsym;
+         typedconsttype.load;
+         prefix:=stringdup(readstring);
+         is_really_const:=boolean(readbyte);
+      end;
+
+
+    destructor ttypedconstsym.done;
+      begin
+         stringdispose(prefix);
+         tsym.done;
+      end;
+
+
+    function ttypedconstsym.mangledname : string;
+      begin
+         mangledname:='TC_'+prefix^+'_'+name;
+      end;
+
+
+    function ttypedconstsym.getsize : longint;
+      begin
+        if assigned(typedconsttype.def) then
+         getsize:=typedconsttype.def^.size
+        else
+         getsize:=0;
+      end;
+
+
+    procedure ttypedconstsym.deref;
+      begin
+        typedconsttype.resolve;
+      end;
+
+
+    procedure ttypedconstsym.write;
+      begin
+         tsym.write;
+         typedconsttype.write;
+         writestring(prefix^);
+         writebyte(byte(is_really_const));
+         current_ppu^.writeentry(ibtypedconstsym);
+      end;
+
+
+    procedure ttypedconstsym.insert_in_data;
+      var
+        curconstsegment : paasmoutput;
+        l,ali,modulo : longint;
+        storefilepos : tfileposinfo;
+      begin
+        storefilepos:=aktfilepos;
+        aktfilepos:=tokenpos;
+        if is_really_const then
+          curconstsegment:=consts
+        else
+          curconstsegment:=datasegment;
+        if (cs_create_smart in aktmoduleswitches) then
+          curconstsegment^.concat(new(pai_cut,init));
+        l:=getsize;
+        ali:=data_align(l);
+        if ali>1 then
+          begin
+             curconstsegment^.concat(new(pai_align,init(ali)));
+             modulo:=owner^.datasize mod ali;
+             if modulo>0 then
+               inc(owner^.datasize,ali-modulo);
+          end;
+        {  Why was there no owner size update here ??? }
+        inc(owner^.datasize,l);
+{$ifdef GDB}
+              if cs_debuginfo in aktmoduleswitches then
+                concatstabto(curconstsegment);
+{$endif GDB}
+        if owner^.symtabletype=globalsymtable then
+          begin
+             curconstsegment^.concat(new(pai_symbol,initdataname_global(mangledname,getsize)));
+          end
+        else
+          if owner^.symtabletype<>unitsymtable then
+            begin
+              if (cs_create_smart in aktmoduleswitches) or
+                 DLLSource then
+                curconstsegment^.concat(new(pai_symbol,initdataname_global(mangledname,getsize)))
+              else
+                curconstsegment^.concat(new(pai_symbol,initdataname(mangledname,getsize)));
+            end;
+        aktfilepos:=storefilepos;
+      end;
+
+{$ifdef GDB}
+    function ttypedconstsym.stabstring : pchar;
+    var
+      st : char;
+    begin
+    if (cs_gdb_gsym in aktglobalswitches) and (owner^.symtabletype in [unitsymtable,globalsymtable]) then
+      st := 'G'
+    else
+      st := 'S';
+    stabstring := strpnew('"'+name+':'+st+
+            typedconsttype.def^.numberstring+'",'+tostr(n_STSYM)+',0,'+
+            tostr(fileinfo.line)+','+mangledname);
+    end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TCONSTSYM
+****************************************************************************}
+
+    constructor tconstsym.init(const n : string;t : tconsttyp;v : TConstExprInt);
+      begin
+         inherited init(n);
+         typ:=constsym;
+         consttyp:=t;
+         value:=v;
+         ResStrIndex:=0;
+         consttype.reset;
+         len:=0;
+      end;
+
+
+    constructor tconstsym.init_def(const n : string;t : tconsttyp;v : TConstExprInt;def : pdef);
+      begin
+         inherited init(n);
+         typ:=constsym;
+         consttyp:=t;
+         value:=v;
+         consttype.setdef(def);
+         len:=0;
+      end;
+
+
+    constructor tconstsym.init_string(const n : string;t : tconsttyp;str:pchar;l:longint);
+      begin
+         inherited init(n);
+         typ:=constsym;
+         consttyp:=t;
+         value:=longint(str);
+         consttype.reset;
+         len:=l;
+         if t=constresourcestring then
+           ResStrIndex:=ResourceStrings^.Register(name,
+             pchar(tpointerord(value)),len);
+      end;
+
+    constructor tconstsym.load;
+      var
+         pd : pbestreal;
+         ps : pnormalset;
+         pc : pchar;
+         l1,l2 : longint;
+
+      begin
+         tsym.load;
+         typ:=constsym;
+         consttype.reset;
+         consttyp:=tconsttyp(readbyte);
+         case consttyp of
+           constint:
+             if sizeof(tconstexprint)=8 then
+               begin
+                  l1:=readlong;
+                  l2:=readlong;
+{$ifopt R+}
+  {$define Range_check_on}
+{$endif opt R+}
+{$R- needed here }
+                  value:=qword(l1)+(int64(l2) shl 32);
+{$ifdef Range_check_on}
+  {$R+}
+  {$undef Range_check_on}
+{$endif Range_check_on}
+               end
+             else
+               value:=readlong;
+           constbool,
+           constchar :
+             value:=readlong;
+           constpointer,
+           constord :
+             begin
+               consttype.load;
+               if sizeof(TConstExprInt)=8 then
+                 begin
+                    l1:=readlong;
+                    l2:=readlong;
+{$ifopt R+}
+  {$define Range_check_on}
+{$endif opt R+}
+{$R- needed here }
+                    value:=qword(l1)+(int64(l2) shl 32);
+{$ifdef Range_check_on}
+  {$R+}
+  {$undef Range_check_on}
+{$endif Range_check_on}
+                 end
+               else
+                 value:=readlong;
+             end;
+           conststring,constresourcestring :
+             begin
+               len:=readlong;
+               getmem(pc,len+1);
+               current_ppu^.getdata(pc^,len);
+               if consttyp=constresourcestring then
+                 ResStrIndex:=readlong;
+               value:=tpointerord(pc);
+             end;
+           constreal :
+             begin
+               new(pd);
+               pd^:=readreal;
+               value:=tpointerord(pd);
+             end;
+           constset :
+             begin
+               consttype.load;
+               new(ps);
+               readnormalset(ps^);
+               value:=tpointerord(ps);
+             end;
+           constnil : ;
+           else
+             Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
+         end;
+      end;
+
+
+    destructor tconstsym.done;
+      begin
+        case consttyp of
+          conststring,constresourcestring :
+            freemem(pchar(tpointerord(value)),len+1);
+          constreal :
+            dispose(pbestreal(tpointerord(value)));
+          constset :
+            dispose(pnormalset(tpointerord(value)));
+        end;
+        inherited done;
+      end;
+
+
+    function tconstsym.mangledname : string;
+      begin
+         mangledname:=name;
+      end;
+
+
+    procedure tconstsym.deref;
+      begin
+        if consttyp in [constord,constpointer,constset] then
+         consttype.resolve;
+      end;
+
+
+    procedure tconstsym.write;
+      begin
+         tsym.write;
+         writebyte(byte(consttyp));
+         case consttyp of
+           constnil : ;
+           constint:
+             if sizeof(TConstExprInt)=8 then
+               begin
+                  writelong(lo(value));
+                  writelong(hi(value));
+               end
+             else
+               writelong(value);
+
+           constbool,
+           constchar :
+             writelong(value);
+           constpointer,
+           constord :
+             begin
+               consttype.write;
+               if sizeof(TConstExprInt)=8 then
+                 begin
+                    writelong(lo(value));
+                    writelong(hi(value));
+                 end
+               else
+                 writelong(value);
+             end;
+           conststring,constresourcestring :
+             begin
+               writelong(len);
+               current_ppu^.putdata(pchar(TPointerOrd(value))^,len);
+               if consttyp=constresourcestring then
+                 writelong(ResStrIndex);
+             end;
+           constreal :
+             writereal(pbestreal(TPointerOrd(value))^);
+           constset :
+             begin
+               consttype.write;
+               writenormalset(pointer(TPointerOrd(value))^);
+             end;
+         else
+           internalerror(13);
+         end;
+        current_ppu^.writeentry(ibconstsym);
+      end;
+
+{$ifdef GDB}
+    function tconstsym.stabstring : pchar;
+    var st : string;
+    begin
+         {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
+         case consttyp of
+            conststring : begin
+                          { I had to remove ibm2ascii !! }
+                          st := pstring(TPointerOrd(value))^;
+                          {st := ibm2ascii(pstring(value)^);}
+                          st := 's'''+st+'''';
+                          end;
+            constbool,
+            constint,
+            constpointer,
+            constord,
+            constchar : st := 'i'+tostr(value);
+            constreal : begin
+                        system.str(pbestreal(TPointerOrd(value))^,st);
+                        st := 'r'+st;
+                        end;
+         { if we don't know just put zero !! }
+         else st:='i0';
+            {***SETCONST}
+            {constset:;}    {*** I don't know what to do with a set.}
+         { sets are not recognized by GDB}
+            {***}
+        end;
+    stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
+                    tostr(fileinfo.line)+',0');
+    end;
+
+    procedure tconstsym.concatstabto(asmlist : paasmoutput);
+      begin
+        if consttyp <> conststring then
+          inherited concatstabto(asmlist);
+      end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TENUMSYM
+****************************************************************************}
+
+    constructor tenumsym.init(const n : string;def : penumdef;v : longint);
+      begin
+         tsym.init(n);
+         typ:=enumsym;
+         definition:=def;
+         value:=v;
+         if def^.min>v then
+           def^.setmin(v);
+         if def^.max<v then
+           def^.setmax(v);
+         order;
+      end;
+
+
+    constructor tenumsym.load;
+      begin
+         tsym.load;
+         typ:=enumsym;
+         definition:=penumdef(readdefref);
+         value:=readlong;
+         nextenum := Nil;
+      end;
+
+
+    procedure tenumsym.deref;
+      begin
+         resolvedef(pdef(definition));
+         order;
+      end;
+
+
+   procedure tenumsym.order;
+      var
+         sym : penumsym;
+      begin
+         sym := definition^.firstenum;
+         if sym = nil then
+          begin
+            definition^.firstenum := @self;
+            nextenum := nil;
+            exit;
+          end;
+         { reorder the symbols in increasing value }
+         if value < sym^.value then
+          begin
+            nextenum := sym;
+            definition^.firstenum := @self;
+          end
+         else
+          begin
+            while (sym^.value <= value) and assigned(sym^.nextenum) do
+             sym := sym^.nextenum;
+            nextenum := sym^.nextenum;
+            sym^.nextenum := @self;
+          end;
+      end;
+
+
+    procedure tenumsym.write;
+      begin
+         tsym.write;
+         writedefref(definition);
+         writelong(value);
+         current_ppu^.writeentry(ibenumsym);
+      end;
+
+
+{$ifdef GDB}
+    procedure tenumsym.concatstabto(asmlist : paasmoutput);
+    begin
+    {enum elements have no stab !}
+    end;
+{$EndIf GDB}
+
+
+{****************************************************************************
+                                  TTYPESYM
+****************************************************************************}
+
+    constructor ttypesym.init(const n : string;const tt : ttype);
+
+      begin
+         tsym.init(n);
+         typ:=typesym;
+         restype:=tt;
+{$ifdef GDB}
+         isusedinstab := false;
+{$endif GDB}
+{$ifdef SYNONYM}
+         if assigned(restype.def) then
+          begin
+             if not(assigned(restype.def^.typesym)) then
+               begin
+                  restype.def^.typesym:=@self;
+                  synonym:=nil;
+                  include(symoptions,sp_primary_typesym);
+               end
+             else
+               begin
+                  synonym:=restype.def^.typesym^.synonym;
+                  restype.def^.typesym^.synonym:=@self;
+               end;
+          end;
+{$else}
+        { register the typesym for the definition }
+        if assigned(restype.def) and
+           not(assigned(restype.def^.typesym)) then
+         restype.def^.typesym:=@self;
+{$endif}
+      end;
+
+    constructor ttypesym.initdef(const n : string;d : pdef);
+      var
+        t : ttype;
+      begin
+        t.setdef(d);
+        ttypesym.init(n,t);
+      end;
+
+    constructor ttypesym.load;
+      begin
+         tsym.load;
+         typ:=typesym;
+{$ifdef SYNONYM}
+         synonym:=nil;
+{$endif}
+{$ifdef GDB}
+         isusedinstab := false;
+{$endif GDB}
+         restype.load;
+      end;
+
+{$ifdef SYNONYM}
+    destructor ttypesym.done;
+      var
+        prevsym : ptypesym;
+      begin
+         if assigned(restype.def) then
+           begin
+              prevsym:=restype.def^.typesym;
+              if prevsym=@self then
+                restype.def^.typesym:=synonym;
+              while assigned(prevsym) do
+                begin
+                   if (prevsym^.synonym=@self) then
+                     begin
+                        prevsym^.synonym:=synonym;
+                        break;
+                     end;
+                   prevsym:=prevsym^.synonym;
+                end;
+           end;
+         synonym:=nil;
+         inherited done;
+      end;
+{$endif}
+
+
+    procedure ttypesym.prederef;
+      begin
+         restype.resolve;
+{$ifdef SYNONYM}
+         if assigned(restype.def) then
+          begin
+            if (sp_primary_typesym in symoptions) then
+              begin
+                 if restype.def^.typesym<>@self then
+                   synonym:=restype.def^.typesym;
+                 restype.def^.typesym:=@self;
+              end
+            else
+              begin
+                 if assigned(restype.def^.typesym) then
+                   begin
+                      synonym:=restype.def^.typesym^.synonym;
+                      if restype.def^.typesym<>@self then
+                        restype.def^.typesym^.synonym:=@self;
+                   end
+                 else
+                   restype.def^.typesym:=@self;
+              end;
+            if (restype.def^.deftype=recorddef) and assigned(precorddef(restype.def)^.symtable) and
+               (restype.def^.typesym=@self) then
+              precorddef(restype.def)^.symtable^.name:=stringdup('record '+name);
+          end;
+{$endif}
+         {KAZ: another test for system unit: current_module^.used_units.first is nil iif system unit}
+         if not assigned(rec_tguid) and { system unit loaded first and TGUID be defined in system unit }
+            (_name^='TGUID') and { name: TGUID and size=16 bytes that is 128 bits }
+            assigned(restype.def) and (restype.def^.size=16) then
+           rec_tguid:=precorddef(restype.def);
+      end;
+
+
+    procedure ttypesym.write;
+      begin
+         tsym.write;
+         restype.write;
+         current_ppu^.writeentry(ibtypesym);
+      end;
+
+
+    procedure ttypesym.load_references;
+      begin
+         inherited load_references;
+         if (restype.def^.deftype=recorddef) then
+           precorddef(restype.def)^.symtable^.load_browser;
+         if (restype.def^.deftype=objectdef) then
+           pobjectdef(restype.def)^.symtable^.load_browser;
+      end;
+
+
+    function ttypesym.write_references : boolean;
+      begin
+        if not inherited write_references then
+         { write address of this symbol if record or object
+           even if no real refs are there
+           because we need it for the symtable }
+         if (restype.def^.deftype=recorddef) or
+            (restype.def^.deftype=objectdef) then
+          begin
+            writesymref(@self);
+            current_ppu^.writeentry(ibsymref);
+          end;
+         write_references:=true;
+         if (restype.def^.deftype=recorddef) then
+           precorddef(restype.def)^.symtable^.write_browser;
+         if (restype.def^.deftype=objectdef) then
+           pobjectdef(restype.def)^.symtable^.write_browser;
+      end;
+
+
+{$ifdef BrowserLog}
+    procedure ttypesym.add_to_browserlog;
+      begin
+         inherited add_to_browserlog;
+         if (restype.def^.deftype=recorddef) then
+           precorddef(restype.def)^.symtable^.writebrowserlog;
+         if (restype.def^.deftype=objectdef) then
+           pobjectdef(restype.def)^.symtable^.writebrowserlog;
+      end;
+{$endif BrowserLog}
+
+
+{$ifdef GDB}
+    function ttypesym.stabstring : pchar;
+    var
+      stabchar : string[2];
+      short : string;
+    begin
+      if restype.def^.deftype in tagtypes then
+        stabchar := 'Tt'
+      else
+        stabchar := 't';
+      short := '"'+name+':'+stabchar+restype.def^.numberstring
+               +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
+      stabstring := strpnew(short);
+    end;
+
+    procedure ttypesym.concatstabto(asmlist : paasmoutput);
+      begin
+      {not stabs for forward defs }
+      if assigned(restype.def) then
+        if (restype.def^.typesym = @self) then
+          restype.def^.concatstabto(asmlist)
+        else
+          inherited concatstabto(asmlist);
+      end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TSYSSYM
+****************************************************************************}
+
+    constructor tsyssym.init(const n : string;l : longint);
+      begin
+         inherited init(n);
+         typ:=syssym;
+         number:=l;
+      end;
+
+    constructor tsyssym.load;
+      begin
+         tsym.load;
+         typ:=syssym;
+         number:=readlong;
+      end;
+
+    destructor tsyssym.done;
+      begin
+        inherited done;
+      end;
+
+    procedure tsyssym.write;
+      begin
+         tsym.write;
+         writelong(number);
+         current_ppu^.writeentry(ibsyssym);
+      end;
+
+{$ifdef GDB}
+    procedure tsyssym.concatstabto(asmlist : paasmoutput);
+      begin
+      end;
+{$endif GDB}
+
+
+{****************************************************************************
+                                  TMACROSYM
+****************************************************************************}
+
+    constructor tmacrosym.init(const n : string);
+      begin
+         inherited init(n);
+         typ:=macrosym;
+         defined:=true;
+         defined_at_startup:=false;
+         is_used:=false;
+         buftext:=nil;
+         buflen:=0;
+      end;
+
+    destructor tmacrosym.done;
+      begin
+         if assigned(buftext) then
+           freemem(buftext,buflen);
+         inherited done;
+      end;
+
+
+{
+  $Log$
+  Revision 1.13  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.12  2000/10/31 22:02:52  peter
+    * symtable splitted, no real code changes
+
+  Revision 1.11  2000/10/21 18:16:12  florian
+    * a lot of changes:
+       - basic dyn. array support
+       - basic C++ support
+       - some work for interfaces done
+       ....
+
+  Revision 1.10  2000/10/15 07:47:53  peter
+    * unit names and procedure names are stored mixed case
+
+  Revision 1.9  2000/09/24 21:19:52  peter
+    * delphi compile fixes
+
+  Revision 1.8  2000/09/19 23:08:03  pierre
+   * fixes for local class debuggging problem (merged)
+
+  Revision 1.7  2000/08/27 20:19:39  peter
+    * store strings with case in ppu, when an internal symbol is created
+      a '$' is prefixed so it's not automatic uppercased
+
+  Revision 1.6  2000/08/21 11:27:44  pierre
+   * fix the stabs problems
+
+  Revision 1.5  2000/08/16 13:06:07  florian
+    + support of 64 bit integer constants
+
+  Revision 1.4  2000/08/13 12:54:56  peter
+    * class member decl wrong then no other error after it
+    * -vb has now also line numbering
+    * -vb is also used for interface/implementation different decls and
+      doesn't list the current function (merged)
+
+  Revision 1.3  2000/07/13 12:08:27  michael
+  + patched to 1.1.0 with former 1.09patch from peter
+
+  Revision 1.2  2000/07/13 11:32:49  michael
+  + removed logs
+
+}

+ 58 - 9
compiler/symtable.pas

@@ -120,13 +120,24 @@ interface
        lastsrsym      : psym;           { last sym found in statement }
        lastsrsym      : psym;           { last sym found in statement }
        lastsrsymtable : psymtable;
        lastsrsymtable : psymtable;
        lastsymknown   : boolean;
        lastsymknown   : boolean;
-
        constsymtable  : psymtable;      { symtable were the constants can be inserted }
        constsymtable  : psymtable;      { symtable were the constants can be inserted }
-
        systemunit     : punitsymtable;  { pointer to the system unit }
        systemunit     : punitsymtable;  { pointer to the system unit }
-
        read_member : boolean;      { reading members of an symtable }
        read_member : boolean;      { reading members of an symtable }
 
 
+       aktprocsym : pprocsym;      { pointer to the symbol for the
+                                     currently be parsed procedure }
+
+       aktcallprocsym : pprocsym;  { pointer to the symbol for the
+                                     currently be called procedure,
+                                     only set/unset in firstcall }
+
+       aktvarsym : pvarsym;     { pointer to the symbol for the
+                                     currently read var, only used
+                                     for variable directives }
+
+       procprefix : string;     { eindeutige Namen bei geschachtel- }
+                                   { ten Unterprogrammen erzeugen      }
+
        lexlevel : longint;       { level of code                     }
        lexlevel : longint;       { level of code                     }
                                    { 1 for main procedure             }
                                    { 1 for main procedure             }
                                    { 2 for normal function or proc     }
                                    { 2 for normal function or proc     }
@@ -218,6 +229,8 @@ implementation
 {$ifdef GDB}
 {$ifdef GDB}
       gdb,
       gdb,
 {$endif GDB}
 {$endif GDB}
+      { type helpers }
+      types,
       { scanner }
       { scanner }
       scanner,
       scanner,
       { codegen }
       { codegen }
@@ -309,12 +322,12 @@ implementation
              begin
              begin
                 if (psym(p)^.owner^.symtabletype=parasymtable) then
                 if (psym(p)^.owner^.symtabletype=parasymtable) then
                   begin
                   begin
-                    if (pvarsym(p)^.varspez<>vs_var)  then
+                    if not(pvarsym(p)^.varspez in [vs_var,vs_out])  then
                       MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name)
                       MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name)
                   end
                   end
                 else if (vo_is_local_copy in pvarsym(p)^.varoptions) then
                 else if (vo_is_local_copy in pvarsym(p)^.varoptions) then
                   begin
                   begin
-                    if (pvarsym(p)^.varspez<>vs_var) then
+                    if not(pvarsym(p)^.varspez in [vs_var,vs_out]) then
                       MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name);
                       MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name);
                   end
                   end
                 else if (psym(p)^.owner^.symtabletype=objectsymtable) then
                 else if (psym(p)^.owner^.symtabletype=objectsymtable) then
@@ -1038,7 +1051,7 @@ implementation
                    { delphi allows to reuse the names in a class, but not
                    { delphi allows to reuse the names in a class, but not
                      in object (tp7 compatible) }
                      in object (tp7 compatible) }
                    if not((m_delphi in aktmodeswitches) and
                    if not((m_delphi in aktmodeswitches) and
-                          (pobjectdef(next^.next^.defowner)^.is_class)) then
+                          is_class(pdef(next^.next^.defowner))) then
                     begin
                     begin
                       DuplicateSym(hsym);
                       DuplicateSym(hsym);
                       exit;
                       exit;
@@ -1065,7 +1078,7 @@ implementation
                    { delphi allows to reuse the names in a class, but not
                    { delphi allows to reuse the names in a class, but not
                      in object (tp7 compatible) }
                      in object (tp7 compatible) }
                    if not((m_delphi in aktmodeswitches) and
                    if not((m_delphi in aktmodeswitches) and
-                          (procinfo^._class^.is_class)) then
+                          is_class(procinfo^._class)) then
                     begin
                     begin
                       DuplicateSym(hsym);
                       DuplicateSym(hsym);
                       exit;
                       exit;
@@ -2353,11 +2366,47 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.13  2000-11-01 23:04:38  peter
+  Revision 1.14  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.13  2000/11/01 23:04:38  peter
     * tprocdef.fullprocname added for better casesensitve writing of
     * tprocdef.fullprocname added for better casesensitve writing of
       procedures
       procedures
 
 
   Revision 1.12  2000/10/31 22:02:52  peter
   Revision 1.12  2000/10/31 22:02:52  peter
     * symtable splitted, no real code changes
     * symtable splitted, no real code changes
 
 
-}
+  Revision 1.11  2000/10/15 07:47:53  peter
+    * unit names and procedure names are stored mixed case
+
+  Revision 1.10  2000/10/14 10:14:53  peter
+    * moehrendorf oct 2000 rewrite
+
+  Revision 1.9  2000/10/01 19:48:25  peter
+    * lot of compile updates for cg11
+
+  Revision 1.8  2000/09/24 15:06:29  peter
+    * use defines.inc
+
+  Revision 1.7  2000/08/27 16:11:54  peter
+    * moved some util functions from globals,cobjects to cutils
+    * splitted files into finput,fmodule
+
+  Revision 1.6  2000/08/21 11:27:45  pierre
+   * fix the stabs problems
+
+  Revision 1.5  2000/08/20 14:58:41  peter
+    * give fatal if objfpc/delphi mode things are found (merged)
+
+  Revision 1.4  2000/08/16 18:33:54  peter
+    * splitted namedobjectitem.next into indexnext and listnext so it
+      can be used in both lists
+    * don't allow "word = word" type definitions (merged)
+
+  Revision 1.3  2000/08/08 19:28:57  peter
+    * memdebug/memory patches (merged)
+    * only once illegal directive (merged)
+
+  Revision 1.2  2000/07/13 11:32:50  michael
+  + removed logs
+}

+ 45 - 27
compiler/temp_gen.pas

@@ -31,7 +31,9 @@ interface
       hcodegen,verbose,fmodule,aasm;
       hcodegen,verbose,fmodule,aasm;
 
 
     type
     type
-      ttemptype = (tt_none,tt_free,tt_normal,tt_persistant,tt_ansistring,tt_freeansistring,tt_widestring,tt_freewidestring);
+      ttemptype = (tt_none,tt_free,tt_normal,tt_persistant,
+                   tt_ansistring,tt_freeansistring,tt_widestring,tt_freewidestring,
+                   tt_interfacecom,tt_freeinterfacecom);
       ttemptypeset = set of ttemptype;
       ttemptypeset = set of ttemptype;
 
 
       ptemprecord = ^ttemprecord;
       ptemprecord = ^ttemprecord;
@@ -72,9 +74,12 @@ interface
     procedure gettempofsizereference(l : longint;var ref : treference);
     procedure gettempofsizereference(l : longint;var ref : treference);
     function istemp(const ref : treference) : boolean;
     function istemp(const ref : treference) : boolean;
     procedure ungetiftemp(const ref : treference);
     procedure ungetiftemp(const ref : treference);
+
     function ungetiftempansi(const ref : treference) : boolean;
     function ungetiftempansi(const ref : treference) : boolean;
     procedure gettempansistringreference(var ref : treference);
     procedure gettempansistringreference(var ref : treference);
 
 
+    function ungetiftempintfcom(const ref : treference) : boolean;
+    procedure gettempintfcomreference(var ref : treference);
 
 
   implementation
   implementation
 
 
@@ -293,19 +298,19 @@ const
       end;
       end;
 
 
 
 
-    procedure gettempansistringreference(var ref : treference);
+    procedure gettemppointerreferencefortype(var ref : treference; const usedtype, freetype: ttemptype);
       var
       var
          foundslot,tl : ptemprecord;
          foundslot,tl : ptemprecord;
       begin
       begin
          { do a reset, because the reference isn't used }
          { do a reset, because the reference isn't used }
          reset_reference(ref);
          reset_reference(ref);
          ref.base:=procinfo^.framepointer;
          ref.base:=procinfo^.framepointer;
-         { Reuse old ansi slot ? }
+         { Reuse old slot ? }
          foundslot:=nil;
          foundslot:=nil;
          tl:=templist;
          tl:=templist;
          while assigned(tl) do
          while assigned(tl) do
           begin
           begin
-            if tl^.temptype=tt_freeansistring then
+            if tl^.temptype=freetype then
              begin
              begin
                foundslot:=tl;
                foundslot:=tl;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
@@ -317,16 +322,8 @@ const
           end;
           end;
          if assigned(foundslot) then
          if assigned(foundslot) then
           begin
           begin
-            foundslot^.temptype:=tt_ansistring;
+            foundslot^.temptype:=usedtype;
             ref.offset:=foundslot^.pos;
             ref.offset:=foundslot^.pos;
-            { we're reusing an old slot then set the function result to true
-              so that we can call a decr_ansistr }
-
-            { we never know if a slot was used previously:
-              imagine a loop: in the first run the slot wasn't used
-              while in later runs it is reused (FK)
-            gettempansistringreference:=true;
-            }
           end
           end
          else
          else
           begin
           begin
@@ -334,37 +331,32 @@ const
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
             templist^.posinfo:=aktfilepos;
             templist^.posinfo:=aktfilepos;
 {$endif}
 {$endif}
-            templist^.temptype:=tt_ansistring;
-            { set result to false, we don't need an decr_ansistr
-              gettempansistringreference:=true;
-              Not necessary, the above (FK)
-            }
+            templist^.temptype:=usedtype;
           end;
           end;
          exprasmlist^.concat(new(paitempalloc,alloc(ref.offset,target_os.size_of_pointer)));
          exprasmlist^.concat(new(paitempalloc,alloc(ref.offset,target_os.size_of_pointer)));
       end;
       end;
 
 
-
-    function ungetiftempansi(const ref : treference) : boolean;
+    function ungettemppointeriftype(const ref : treference; const usedtype, freetype: ttemptype) : boolean;
       var
       var
          tl : ptemprecord;
          tl : ptemprecord;
       begin
       begin
-        ungetiftempansi:=false;
+        ungettemppointeriftype:=false;
         tl:=templist;
         tl:=templist;
         while assigned(tl) do
         while assigned(tl) do
          begin
          begin
            if tl^.pos=ref.offset then
            if tl^.pos=ref.offset then
             begin
             begin
-              if tl^.temptype=tt_ansistring then
+              if tl^.temptype=usedtype then
                begin
                begin
-                 tl^.temptype:=tt_freeansistring;
-                 ungetiftempansi:=true;
+                 tl^.temptype:=freetype;
+                 ungettemppointeriftype:=true;
                  exprasmlist^.concat(new(paitempalloc,dealloc(tl^.pos,tl^.size)));
                  exprasmlist^.concat(new(paitempalloc,dealloc(tl^.pos,tl^.size)));
                  exit;
                  exit;
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
                end
                end
-              else if (tl^.temptype=tt_freeansistring) then
+              else if (tl^.temptype=freetype) then
                begin
                begin
-                 Comment(V_Debug,'temp ansi managment problem : ungetiftempansi()'+
+                 Comment(V_Debug,'temp managment problem : ungettemppointeriftype()'+
                      ' at pos '+tostr(ref.offset)+ ' already free !');
                      ' at pos '+tostr(ref.offset)+ ' already free !');
 {$endif}
 {$endif}
                end;
                end;
@@ -373,6 +365,29 @@ const
          end;
          end;
       end;
       end;
 
 
+
+    procedure gettempansistringreference(var ref : treference);
+      begin
+        gettemppointerreferencefortype(ref,tt_ansistring,tt_freeansistring);
+      end;
+
+    function ungetiftempansi(const ref : treference) : boolean;
+      begin
+        ungetiftempansi:=ungettemppointeriftype(ref,tt_ansistring,tt_freeansistring);
+      end;
+
+
+    procedure gettempintfcomreference(var ref : treference);
+      begin
+        gettemppointerreferencefortype(ref,tt_interfacecom,tt_freeinterfacecom);
+      end;
+
+
+    function ungetiftempintfcom(const ref : treference) : boolean;
+      begin
+        ungetiftempintfcom:=ungettemppointeriftype(ref,tt_ansistring,tt_freeansistring);
+      end;
+
     function istemp(const ref : treference) : boolean;
     function istemp(const ref : treference) : boolean;
 
 
       begin
       begin
@@ -542,7 +557,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.5  2000-09-30 16:08:45  peter
+  Revision 1.6  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.5  2000/09/30 16:08:45  peter
     * more cg11 updates
     * more cg11 updates
 
 
   Revision 1.4  2000/09/24 15:06:31  peter
   Revision 1.4  2000/09/24 15:06:31  peter

+ 38 - 21
compiler/types.pas

@@ -174,7 +174,9 @@ interface
           tc_proc_2_procvar,
           tc_proc_2_procvar,
           tc_arrayconstructor_2_set,
           tc_arrayconstructor_2_set,
           tc_load_smallset,
           tc_load_smallset,
-          tc_cord_2_pointer
+          tc_cord_2_pointer,
+          tc_intf_2_string,
+          tc_intf_2_guid
        );
        );
 
 
     function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
     function assignment_overloaded(from_def,to_def : pdef) : pprocdef;
@@ -184,7 +186,8 @@ interface
        1 - Convertable
        1 - Convertable
        2 - Convertable, but not first choice }
        2 - Convertable, but not first choice }
     function isconvertable(def_from,def_to : pdef;
     function isconvertable(def_from,def_to : pdef;
-             var doconv : tconverttype;fromtreetype : tnodetype;
+             var doconv : tconverttype;
+             fromtree: tnode; fromtreetype : tnodetype;
              explicit : boolean) : byte;
              explicit : boolean) : byte;
 
 
     { same as is_equal, but with error message if failed }
     { same as is_equal, but with error message if failed }
@@ -234,7 +237,7 @@ implementation
 
 
     uses
     uses
        globtype,globals,tokens,verbose,
        globtype,globals,tokens,verbose,
-       symconst,symtable;
+       symconst,symtable,nld;
 
 
     var
     var
        b_needs_init_final : boolean;
        b_needs_init_final : boolean;
@@ -243,8 +246,7 @@ implementation
       begin
       begin
          if (psym(p)^.typ=varsym) and
          if (psym(p)^.typ=varsym) and
            assigned(pvarsym(p)^.vartype.def) and
            assigned(pvarsym(p)^.vartype.def) and
-           not((pvarsym(p)^.vartype.def^.deftype=objectdef) and
-           pobjectdef(pvarsym(p)^.vartype.def)^.is_class) and
+           not is_class(pvarsym(p)^.vartype.def) and
            pstoreddef(pvarsym(p)^.vartype.def)^.needs_inittable then
            pstoreddef(pvarsym(p)^.vartype.def)^.needs_inittable then
            b_needs_init_final:=true;
            b_needs_init_final:=true;
       end;
       end;
@@ -380,7 +382,7 @@ implementation
               case acp of
               case acp of
               cp_value_equal_const :
               cp_value_equal_const :
                 begin
                 begin
-                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,callparan,false)=0) or
+                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,nil,callparan,false)=0) or
                      ((def1^.paratyp<>def2^.paratyp) and
                      ((def1^.paratyp<>def2^.paratyp) and
                       ((def1^.paratyp in [vs_out,vs_var]) or
                       ((def1^.paratyp in [vs_out,vs_var]) or
                        (def2^.paratyp in [vs_out,vs_var])
                        (def2^.paratyp in [vs_out,vs_var])
@@ -393,7 +395,7 @@ implementation
                 end;
                 end;
               cp_all :
               cp_all :
                 begin
                 begin
-                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,callparan,false)=0) or
+                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,nil,callparan,false)=0) or
                      (def1^.paratyp<>def2^.paratyp) then
                      (def1^.paratyp<>def2^.paratyp) then
                      begin
                      begin
                         convertable_paras:=false;
                         convertable_paras:=false;
@@ -402,7 +404,7 @@ implementation
                 end;
                 end;
               cp_none :
               cp_none :
                 begin
                 begin
-                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,callparan,false)=0) then
+                   if (isconvertable(def1^.paratype.def,def2^.paratype.def,doconv,nil,callparan,false)=0) then
                      begin
                      begin
                         convertable_paras:=false;
                         convertable_paras:=false;
                         exit;
                         exit;
@@ -695,7 +697,7 @@ implementation
          ret_in_acc:=(def^.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
          ret_in_acc:=(def^.deftype in [orddef,pointerdef,enumdef,classrefdef]) or
                      ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_ansistring,st_widestring])) or
                      ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_ansistring,st_widestring])) or
                      ((def^.deftype=procvardef) and not(po_methodpointer in pprocvardef(def)^.procoptions)) or
                      ((def^.deftype=procvardef) and not(po_methodpointer in pprocvardef(def)^.procoptions)) or
-                     ((def^.deftype=objectdef) and pobjectdef(def)^.is_class) or
+                     not is_object(def) or
                      ((def^.deftype=setdef) and (psetdef(def)^.settype=smallset)) or
                      ((def^.deftype=setdef) and (psetdef(def)^.settype=smallset)) or
                      ((def^.deftype=floatdef) and (pfloatdef(def)^.typ=f32bit));
                      ((def^.deftype=floatdef) and (pfloatdef(def)^.typ=f32bit));
       end;
       end;
@@ -714,7 +716,7 @@ implementation
          ret_in_param:=(def^.deftype in [arraydef,recorddef]) or
          ret_in_param:=(def^.deftype in [arraydef,recorddef]) or
            ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
            ((def^.deftype=stringdef) and (pstringdef(def)^.string_typ in [st_shortstring,st_longstring])) or
            ((def^.deftype=procvardef) and (po_methodpointer in pprocvardef(def)^.procoptions)) or
            ((def^.deftype=procvardef) and (po_methodpointer in pprocvardef(def)^.procoptions)) or
-           ((def^.deftype=objectdef) and not(pobjectdef(def)^.is_class)) or
+           is_object(def) or
            ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
            ((def^.deftype=setdef) and (psetdef(def)^.settype<>smallset));
       end;
       end;
 
 
@@ -746,7 +748,7 @@ implementation
                                 is_array_of_const(def) or
                                 is_array_of_const(def) or
                                 is_array_constructor(def);
                                 is_array_constructor(def);
              objectdef :
              objectdef :
-               push_addr_param:=not(pobjectdef(def)^.is_class);
+               push_addr_param:=is_object(def);
              stringdef :
              stringdef :
                push_addr_param:=pstringdef(def)^.string_typ in [st_shortstring,st_longstring];
                push_addr_param:=pstringdef(def)^.string_typ in [st_shortstring,st_longstring];
              procvardef :
              procvardef :
@@ -1184,7 +1186,7 @@ implementation
             begin
             begin
               if is_equal(passproc^.rettype.def,to_def) and
               if is_equal(passproc^.rettype.def,to_def) and
                  (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
                  (is_equal(pparaitem(passproc^.para^.first)^.paratype.def,from_def) or
-                 (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,ordconstn,false)=1)) then
+                 (isconvertable(from_def,pparaitem(passproc^.para^.first)^.paratype.def,convtyp,nil,ordconstn,false)=1)) then
                 begin
                 begin
                    assignment_overloaded:=passproc;
                    assignment_overloaded:=passproc;
                    break;
                    break;
@@ -1199,7 +1201,8 @@ implementation
        1 - Convertable
        1 - Convertable
        2 - Convertable, but not first choice }
        2 - Convertable, but not first choice }
     function isconvertable(def_from,def_to : pdef;
     function isconvertable(def_from,def_to : pdef;
-             var doconv : tconverttype;fromtreetype : tnodetype;
+             var doconv : tconverttype;
+             fromtree: tnode; fromtreetype : tnodetype;
              explicit : boolean) : byte;
              explicit : boolean) : byte;
 
 
       { Tbasetype:  uauto,uvoid,uchar,
       { Tbasetype:  uauto,uvoid,uchar,
@@ -1398,7 +1401,7 @@ implementation
                             end
                             end
                            else
                            else
                             if isconvertable(parraydef(def_from)^.elementtype.def,
                             if isconvertable(parraydef(def_from)^.elementtype.def,
-                                             parraydef(def_to)^.elementtype.def,hct,arrayconstructorn,false)<>0 then
+                                             parraydef(def_to)^.elementtype.def,hct,nil,arrayconstructorn,false)<>0 then
                              begin
                              begin
                                doconv:=hct;
                                doconv:=hct;
                                b:=2;
                                b:=2;
@@ -1508,7 +1511,7 @@ implementation
                      { class types and class reference type
                      { class types and class reference type
                        can be assigned to void pointers      }
                        can be assigned to void pointers      }
                      if (
                      if (
-                         ((def_from^.deftype=objectdef) and pobjectdef(def_from)^.is_class) or
+                         is_class_or_interface(def_from) or
                          (def_from^.deftype=classrefdef)
                          (def_from^.deftype=classrefdef)
                         ) and
                         ) and
                         (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
                         (ppointerdef(def_to)^.pointertype.def^.deftype=orddef) and
@@ -1572,7 +1575,7 @@ implementation
                 end
                 end
                else
                else
                { Class specific }
                { Class specific }
-                if (pobjectdef(def_to)^.is_class) then
+                if is_class_or_interface(def_to) then
                  begin
                  begin
                    { void pointer also for delphi mode }
                    { void pointer also for delphi mode }
                    if (m_delphi in aktmodeswitches) and
                    if (m_delphi in aktmodeswitches) and
@@ -1583,7 +1586,7 @@ implementation
                     end
                     end
                    else
                    else
                    { nil is compatible with class instances }
                    { nil is compatible with class instances }
-                    if (fromtreetype=niln) and (pobjectdef(def_to)^.is_class) then
+                    if (fromtreetype=niln) and is_class(def_to) then
                      begin
                      begin
                        doconv:=tc_equal;
                        doconv:=tc_equal;
                        b:=1;
                        b:=1;
@@ -1648,9 +1651,20 @@ implementation
 
 
            else
            else
              begin
              begin
-             { assignment overwritten ?? }
-               if assignment_overloaded(def_from,def_to)<>nil then
-                b:=2;
+                { Interface 2 GUID handling }
+                if (def_from^.deftype=errordef) and (def_to=pdef(rec_tguid)) and
+                   assigned(fromtree) and (fromtree.nodetype=typen) and
+                   assigned(ttypenode(fromtree).typenodetype) and
+                   is_interface(ttypenode(fromtree).typenodetype) and
+                   pobjectdef(ttypenode(fromtree).typenodetype)^.isiidguidvalid then
+                  begin
+                    b:=1;
+                    doconv:=tc_equal;
+                  end
+                else
+                  { assignment overwritten ?? }
+                  if assignment_overloaded(def_from,def_to)<>nil then
+                    b:=2;
              end;
              end;
          end;
          end;
         isconvertable:=b;
         isconvertable:=b;
@@ -1686,7 +1700,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.17  2000-10-31 22:30:13  peter
+  Revision 1.18  2000-11-04 14:25:22  florian
+    + merged Attila's changes for interfaces, not tested yet
+
+  Revision 1.17  2000/10/31 22:30:13  peter
     * merged asm result patch part 2
     * merged asm result patch part 2
 
 
   Revision 1.16  2000/10/31 22:02:55  peter
   Revision 1.16  2000/10/31 22:02:55  peter