mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 12:52:45 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			4127 lines
		
	
	
		
			118 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			4127 lines
		
	
	
		
			118 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| {
 | |
|     $Id$
 | |
|     Copyright (c) 1993-98 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)
 | |
| ****************************************************************************}
 | |
| 
 | |
|     const
 | |
|        { if you change one of the following contants, }
 | |
|        { you have also to change the typinfo unit     }
 | |
|        { and the rtl/i386,template/rttip.inc files    }
 | |
|        tkUnknown       = 0;
 | |
|        tkInteger       = 1;
 | |
|        tkChar          = 2;
 | |
|        tkEnumeration   = 3;
 | |
|        tkFloat         = 4;
 | |
|        tkSet           = 5;
 | |
|        tkMethod        = 6;
 | |
|        tkSString       = 7;
 | |
|        tkString        = tkSString;
 | |
|        tkLString       = 8;
 | |
|        tkAString       = 9;
 | |
|        tkWString       = 10;
 | |
|        tkVariant       = 11;
 | |
|        tkArray         = 12;
 | |
|        tkRecord        = 13;
 | |
|        tkInterface     = 14;
 | |
|        tkClass         = 15;
 | |
|        tkObject        = 16;
 | |
|        tkWChar         = 17;
 | |
|        tkBool          = 18;
 | |
| 
 | |
|        otSByte         = 0;
 | |
|        otUByte         = 1;
 | |
|        otSWord         = 2;
 | |
|        otUWord         = 3;
 | |
|        otSLong         = 4;
 | |
|        otULong         = 5;
 | |
| 
 | |
|        ftSingle        = 0;
 | |
|        ftDouble        = 1;
 | |
|        ftExtended      = 2;
 | |
|        ftComp          = 3;
 | |
|        ftCurr          = 4;
 | |
|        ftFixed16       = 5;
 | |
|        ftFixed32       = 6;
 | |
| 
 | |
| 
 | |
|     constructor tdef.init;
 | |
|       begin
 | |
|          inherited init;
 | |
|          deftype:=abstractdef;
 | |
|          owner := nil;
 | |
|          sym := nil;
 | |
|          savesize := 0;
 | |
|          if registerdef then
 | |
|            symtablestack^.registerdef(@self);
 | |
|          has_rtti:=false;
 | |
|          has_inittable:=false;
 | |
| {$ifdef GDB}
 | |
|          is_def_stab_written := false;
 | |
|          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;
 | |
| 
 | |
| 
 | |
|     constructor tdef.load;
 | |
|       begin
 | |
|          deftype:=abstractdef;
 | |
|          next := nil;
 | |
|          owner := nil;
 | |
|          has_rtti:=false;
 | |
|          has_inittable:=false;
 | |
| {$ifdef GDB}
 | |
|          is_def_stab_written := false;
 | |
|          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;
 | |
|          sym:=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;
 | |
|          while assigned(sym) do
 | |
|            begin
 | |
|               sym^.definition:=nil;
 | |
|               sym:=sym^.synonym;
 | |
|            end;
 | |
| 
 | |
|       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(sym) then
 | |
|          typename:=Upper(sym^.name)
 | |
|         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=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(sym);
 | |
| {$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(sym)) or (not sym^.isusedinstab) then
 | |
|         begin
 | |
|            {set even if debuglist is not defined}
 | |
|            if assigned(sym) then
 | |
|              sym^.isusedinstab := true;
 | |
|            if assigned(debuglist) and not is_def_stab_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(sym) then
 | |
|              begin
 | |
|                 table := sym^.owner;
 | |
|                 if table^.unitid > 0 then
 | |
|                   numberstring := '('+tostr(table^.unitid)+','
 | |
|                   +tostr(sym^.definition^.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(sym) then
 | |
|         begin
 | |
|            sname := sym^.name;
 | |
|            sym_line_no:=sym^.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 ((sym = nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
 | |
|       and not is_def_stab_written then
 | |
|       begin
 | |
|       If cs_gdb_dbx in aktglobalswitches then
 | |
|         begin
 | |
|            { otherwise you get two of each def }
 | |
|            If assigned(sym) then
 | |
|              begin
 | |
|                 if sym^.typ=typesym then
 | |
|                   sym^.isusedinstab:=true;
 | |
|                 if (sym^.owner = nil) or
 | |
|                   ((sym^.owner^.symtabletype = unitsymtable) and
 | |
|                  punitsymtable(sym^.owner)^.dbx_count_ok)  then
 | |
|                 begin
 | |
|                    {with DBX we get the definition from the other objects }
 | |
|                    is_def_stab_written := true;
 | |
|                    exit;
 | |
|                 end;
 | |
|              end;
 | |
|         end;
 | |
|       { to avoid infinite loops }
 | |
|       is_def_stab_written := true;
 | |
|       stab_str := allstabstring;
 | |
|       if asmlist = debuglist then do_count_dbx := true;
 | |
|       { count_dbx(stab_str); moved to GDB.PAS}
 | |
|       asmlist^.concat(new(pai_stabs,init(stab_str)));
 | |
|       end;
 | |
|     end;
 | |
| {$endif GDB}
 | |
| 
 | |
| 
 | |
|     procedure tdef.deref;
 | |
|       begin
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tdef.symderef;
 | |
|       begin
 | |
|         resolvesym(psym(sym));
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     { rtti generation }
 | |
|     procedure tdef.generate_rtti;
 | |
|       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;
 | |
| 
 | |
| 
 | |
|     function tdef.get_rtti_label : string;
 | |
|       begin
 | |
|          if not(has_rtti) then
 | |
|            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(sym) then
 | |
|            begin
 | |
|               str:=sym^.name;
 | |
|               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;
 | |
| 
 | |
| 
 | |
| {****************************************************************************
 | |
|                                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
 | |
|         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_smartlink 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_smartlink 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(globals.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:
 | |
|                   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_smartlink 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_smartlink 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;
 | |
|       const
 | |
|         trans : array[uchar..bool8bit] of byte =
 | |
|           (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
 | |
|       begin
 | |
|          case typ of
 | |
|             bool8bit:
 | |
|               rttilist^.concat(new(pai_const,init_8bit(tkBool)));
 | |
|             uchar:
 | |
|               rttilist^.concat(new(pai_const,init_8bit(tkChar)));
 | |
|             else
 | |
|               rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
 | |
|          end;
 | |
|          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;
 | |
| 
 | |
| 
 | |
|     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');
 | |
| 
 | |
|       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.init(ft : tfiletype;tas : pdef);
 | |
|       begin
 | |
|          inherited init;
 | |
|          deftype:=filedef;
 | |
|          filetype:=ft;
 | |
|          typed_as:=tas;
 | |
|          setsize;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tfiledef.load;
 | |
|       begin
 | |
|          inherited load;
 | |
|          deftype:=filedef;
 | |
|          filetype:=tfiletype(readbyte);
 | |
|          if filetype=ft_typed then
 | |
|            typed_as:=readdefref
 | |
|          else
 | |
|            typed_as:=nil;
 | |
|          setsize;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tfiledef.deref;
 | |
|       begin
 | |
|          if filetype=ft_typed then
 | |
|            resolvedef(typed_as);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tfiledef.setsize;
 | |
|       begin
 | |
|         case filetype of
 | |
|           ft_text : savesize:=572;
 | |
|          ft_typed,
 | |
|        ft_untyped : savesize:=316;
 | |
|         end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tfiledef.write;
 | |
|       begin
 | |
|          inherited write;
 | |
|          writebyte(byte(filetype));
 | |
|          if filetype=ft_typed then
 | |
|            writedefref(typed_as);
 | |
|          current_ppu^.writeentry(ibfiledef);
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     function tfiledef.stabstring : pchar;
 | |
|       begin
 | |
|    {$IfDef GDBknowsfiles}
 | |
|       case filetyp of
 | |
|         ft_typed : stabstring := strpnew('d'+typed_as^.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 ((sym = nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
 | |
|          not is_def_stab_written then
 | |
|         begin
 | |
|         if assigned(typed_as) then forcestabto(asmlist,typed_as);
 | |
|         inherited concatstabto(asmlist);
 | |
|         end;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
|     function tfiledef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          case filetype of
 | |
|            ft_untyped:
 | |
|              gettypename:='File';
 | |
|            ft_typed:
 | |
|              gettypename:='File Of '+typed_as^.typename;
 | |
|            ft_text:
 | |
|              gettypename:='Text'
 | |
|          end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
| 
 | |
| {****************************************************************************
 | |
|                                TPOINTERDEF
 | |
| ****************************************************************************}
 | |
| 
 | |
|     constructor tpointerdef.init(def : pdef);
 | |
|       begin
 | |
|          inherited init;
 | |
|          deftype:=pointerdef;
 | |
|          definition:=def;
 | |
|          is_far:=false;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tpointerdef.initfar(def : pdef);
 | |
|       begin
 | |
|          inherited init;
 | |
|          deftype:=pointerdef;
 | |
|          definition:=def;
 | |
|          is_far:=true;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tpointerdef.load;
 | |
|       begin
 | |
|          inherited load;
 | |
|          deftype:=pointerdef;
 | |
|          { the real address in memory is calculated later (deref) }
 | |
|          definition:=readdefref;
 | |
|          is_far:=(readbyte<>0);
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tpointerdef.deref;
 | |
|       begin
 | |
|          resolvedef(definition);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tpointerdef.write;
 | |
|       begin
 | |
|          inherited write;
 | |
|          writedefref(definition);
 | |
|          writebyte(byte(is_far));
 | |
|          current_ppu^.writeentry(ibpointerdef);
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     function tpointerdef.stabstring : pchar;
 | |
|       begin
 | |
|         stabstring := strpnew('*'+definition^.numberstring);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tpointerdef.concatstabto(asmlist : paasmoutput);
 | |
|       var st,nb : string;
 | |
|           sym_line_no : longint;
 | |
|       begin
 | |
|       if ( (sym=nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
 | |
|          not is_def_stab_written then
 | |
|         begin
 | |
|         if assigned(definition) then
 | |
|           if definition^.deftype in [recorddef,objectdef] then
 | |
|             begin
 | |
|             is_def_stab_written := true;
 | |
|             {to avoid infinite recursion in record with next-like fields }
 | |
|             nb := definition^.numberstring;
 | |
|             is_def_stab_written := false;
 | |
|             if not definition^.is_def_stab_written then
 | |
|               begin
 | |
|               if assigned(definition^.sym) then
 | |
|                 begin
 | |
|                 if assigned(sym) then
 | |
|                   begin
 | |
|                      st := sym^.name;
 | |
|                      sym_line_no:=sym^.fileinfo.line;
 | |
|                   end
 | |
|                 else
 | |
|                   begin
 | |
|                      st := ' ';
 | |
|                      sym_line_no:=0;
 | |
|                   end;
 | |
|                 st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
 | |
|                       +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
 | |
|                 if asmlist = debuglist then do_count_dbx := true;
 | |
|                 asmlist^.concat(new(pai_stabs,init(strpnew(st))));
 | |
|                 end;
 | |
|               end else inherited concatstabto(asmlist);
 | |
|             is_def_stab_written := true;
 | |
|             end else
 | |
|             begin
 | |
|             { p =^p1; p1=^p problem }
 | |
|             is_def_stab_written := true;
 | |
|             forcestabto(asmlist,definition);
 | |
|             is_def_stab_written := false;
 | |
|             inherited concatstabto(asmlist);
 | |
|             end;
 | |
|         end;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
|     function tpointerdef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          gettypename:='^'+definition^.typename;
 | |
|       end;
 | |
| 
 | |
| {****************************************************************************
 | |
|                               TCLASSREFDEF
 | |
| ****************************************************************************}
 | |
| 
 | |
|     constructor tclassrefdef.init(def : pdef);
 | |
|       begin
 | |
|          inherited init(def);
 | |
|          deftype:=classrefdef;
 | |
|          definition:=def;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tclassrefdef.load;
 | |
|       begin
 | |
|          { be careful, tclassdefref inherits from tpointerdef }
 | |
|          tdef.load;
 | |
|          deftype:=classrefdef;
 | |
|          definition:=readdefref;
 | |
|          is_far:=false;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tclassrefdef.write;
 | |
|       begin
 | |
|          { be careful, tclassdefref inherits from tpointerdef }
 | |
|          tdef.write;
 | |
|          writedefref(definition);
 | |
|          current_ppu^.writeentry(ibclassrefdef);
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     function tclassrefdef.stabstring : pchar;
 | |
|       begin
 | |
|          stabstring:=strpnew('');
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
 | |
|       begin
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
|     function tclassrefdef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          gettypename:='Class Of '+definition^.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;
 | |
|          setof:=s;
 | |
| {$ifdef usesmallset}
 | |
|          { small sets only working for i386 PM }
 | |
|          if high<32 then
 | |
|            begin
 | |
|               settype:=smallset;
 | |
|               savesize:=Sizeof(longint);
 | |
|            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;
 | |
|          setof:=readdefref;
 | |
|          settype:=tsettype(readbyte);
 | |
|          case settype of
 | |
|             normset : savesize:=32;
 | |
|             varset : savesize:=readlong;
 | |
|             smallset : savesize:=Sizeof(longint);
 | |
|          end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tsetdef.write;
 | |
|       begin
 | |
|          inherited write;
 | |
|          writedefref(setof);
 | |
|          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) }
 | |
|          if settype=smallset then
 | |
|            stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
 | |
|          else
 | |
|            stabstring := strpnew('S'+setof^.numberstring);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tsetdef.concatstabto(asmlist : paasmoutput);
 | |
|       begin
 | |
|       if ( not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
 | |
|           not is_def_stab_written then
 | |
|         begin
 | |
|           if assigned(setof) then
 | |
|             forcestabto(asmlist,setof);
 | |
|           inherited concatstabto(asmlist);
 | |
|         end;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
| 
 | |
|     procedure tsetdef.deref;
 | |
|       begin
 | |
|          resolvedef(setof);
 | |
|       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(setof^.get_rtti_label)));
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tsetdef.write_child_rtti_data;
 | |
|       begin
 | |
|          setof^.get_rtti_label;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tsetdef.is_publishable : boolean;
 | |
|       begin
 | |
|          is_publishable:=settype=smallset;
 | |
|       end;
 | |
| 
 | |
|     function tsetdef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          gettypename:='Set Of '+setof^.typename;
 | |
|       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;
 | |
|          rangedef:=rd;
 | |
|          definition:=nil;
 | |
|          IsVariant:=false;
 | |
|          IsConstructor:=false;
 | |
|          IsArrayOfConst:=false;
 | |
|          rangenr:=0;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tarraydef.load;
 | |
|       begin
 | |
|          inherited load;
 | |
|          deftype:=arraydef;
 | |
|          { the addresses are calculated later }
 | |
|          definition:=readdefref;
 | |
|          rangedef:=readdefref;
 | |
|          lowrange:=readlong;
 | |
|          highrange:=readlong;
 | |
|          IsArrayOfConst:=boolean(readbyte);
 | |
|          IsVariant:=false;
 | |
|          IsConstructor:=false;
 | |
|          rangenr:=0;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tarraydef.getrangecheckstring : string;
 | |
|       begin
 | |
|          if (cs_smartlink 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_smartlink 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(lowrange)));
 | |
|               datasegment^.concat(new(pai_const,init_32bit(highrange)));
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tarraydef.deref;
 | |
|       begin
 | |
|          resolvedef(definition);
 | |
|          resolvedef(rangedef);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tarraydef.write;
 | |
|       begin
 | |
|          inherited write;
 | |
|          writedefref(definition);
 | |
|          writedefref(rangedef);
 | |
|          writelong(lowrange);
 | |
|          writelong(highrange);
 | |
|          writebyte(byte(IsArrayOfConst));
 | |
|          current_ppu^.writeentry(ibarraydef);
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     function tarraydef.stabstring : pchar;
 | |
|       begin
 | |
|       stabstring := strpnew('ar'+rangedef^.numberstring+';'
 | |
|                     +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tarraydef.concatstabto(asmlist : paasmoutput);
 | |
|       begin
 | |
|       if (not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
 | |
|         and not is_def_stab_written then
 | |
|         begin
 | |
|         {when array are inserted they have no definition yet !!}
 | |
|         if assigned(definition) then
 | |
|           inherited concatstabto(asmlist);
 | |
|         end;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
| 
 | |
|     function tarraydef.elesize : longint;
 | |
|       begin
 | |
|          elesize:=definition^.size;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tarraydef.size : longint;
 | |
|       begin
 | |
|          { dirty hack to overcome an overflow (PFV) }
 | |
|          if highrange=$7fffffff then
 | |
|           size:=$7fffffff
 | |
|          else
 | |
|           size:=(highrange-lowrange+1)*elesize;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tarraydef.alignment : longint;
 | |
|       begin
 | |
|          { alignment is the size of the elements }
 | |
|          alignment:=definition^.size;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tarraydef.needs_inittable : boolean;
 | |
|       begin
 | |
|          needs_inittable:=definition^.needs_inittable;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tarraydef.write_child_rtti_data;
 | |
|       begin
 | |
|          definition^.get_rtti_label;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tarraydef.write_rtti_data;
 | |
|       begin
 | |
|          rttilist^.concat(new(pai_const,init_8bit(13)));
 | |
|          write_rtti_name;
 | |
|          { size of elements }
 | |
|          rttilist^.concat(new(pai_const,init_32bit(definition^.size)));
 | |
|          { count of elements }
 | |
|          rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
 | |
|          { element type }
 | |
|          rttilist^.concat(new(pai_const_symbol,initname(definition^.get_rtti_label)));
 | |
|       end;
 | |
| 
 | |
|     function tarraydef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          if isarrayofconst or isConstructor then
 | |
|            gettypename:='Array Of Const'
 | |
|          else if is_open_array(@self) then
 | |
|            gettypename:='Array Of '+definition^.typename
 | |
|          else
 | |
|            begin
 | |
|               if rangedef^.deftype=enumdef then
 | |
|                 gettypename:='Array['+rangedef^.typename+'] Of '+definition^.typename
 | |
|               else
 | |
|                 gettypename:='Array['+tostr(lowrange)+'..'+
 | |
|                   tostr(highrange)+'] Of '+definition^.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 (psym(s)^.typ=varsym) and
 | |
|             ((pvarsym(s)^.definition^.deftype<>objectdef) or
 | |
|              not(pobjectdef(pvarsym(s)^.definition)^.is_class)) then
 | |
|             binittable:=pvarsym(s)^.definition^.needs_inittable;
 | |
|       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({$ifndef TP}@{$endif}check_rec_inittable);
 | |
|          needs_inittable:=binittable;
 | |
|          binittable:=oldb;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure trecorddef.deref;
 | |
|       var
 | |
|          oldrecsyms : psymtable;
 | |
|       begin
 | |
|          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;
 | |
|       begin
 | |
|         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[2];
 | |
|       size : longint;
 | |
|     begin
 | |
|     { static variables from objects are like global objects }
 | |
|     if (sp_static in psym(p)^.symoptions) then
 | |
|       exit;
 | |
|     if (sp_protected in psym(p)^.symoptions) then
 | |
|       spec:='/1'
 | |
|     else if (sp_private in psym(p)^.symoptions) then
 | |
|       spec:='/0'
 | |
|     else
 | |
|       spec:='';
 | |
| 
 | |
|     If psym(p)^.typ = varsym then
 | |
|        begin
 | |
|        size:=pvarsym(p)^.definition^.size;
 | |
|        { open arrays made overflows !! }
 | |
|        if size>$fffffff then
 | |
|          size:=$fffffff;
 | |
|        newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.definition^.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)^.definition^.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({$ifndef TP}@{$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(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
 | |
|            (not is_def_stab_written) then
 | |
|           inherited concatstabto(asmlist);
 | |
|       end;
 | |
| 
 | |
| {$endif GDB}
 | |
| 
 | |
|     var
 | |
|        count : longint;
 | |
|     procedure count_inittable_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          if (psym(sym)^.typ=varsym) and
 | |
|             (pvarsym(sym)^.definition^.needs_inittable) then
 | |
|            inc(count);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure count_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          inc(count);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure write_field_inittable(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          if (psym(sym)^.typ=varsym) and
 | |
|             pvarsym(sym)^.definition^.needs_inittable then
 | |
|            begin
 | |
|               rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.definition^.get_inittable_label)));
 | |
|               rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure write_field_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.definition^.get_rtti_label)));
 | |
|          rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure generate_child_inittable(sym:pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          if (psym(sym)^.typ=varsym) and
 | |
|             pvarsym(sym)^.definition^.needs_inittable then
 | |
|          { force inittable generation }
 | |
|            pvarsym(sym)^.definition^.get_inittable_label;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure generate_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          pvarsym(sym)^.definition^.get_rtti_label;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure trecorddef.write_child_rtti_data;
 | |
|       begin
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure trecorddef.write_child_init_data;
 | |
|       begin
 | |
|          symtable^.foreach({$ifndef TP}@{$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({$ifndef TP}@{$endif}count_fields);
 | |
|          rttilist^.concat(new(pai_const,init_32bit(count)));
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure trecorddef.write_init_data;
 | |
|       begin
 | |
|          rttilist^.concat(new(pai_const,init_8bit(14)));
 | |
|          write_rtti_name;
 | |
|          rttilist^.concat(new(pai_const,init_32bit(size)));
 | |
|          count:=0;
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
 | |
|          rttilist^.concat(new(pai_const,init_32bit(count)));
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
 | |
|       end;
 | |
| 
 | |
|     function trecorddef.gettypename : string;
 | |
| 
 | |
|       begin
 | |
|          gettypename:='<record type>'
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {***************************************************************************
 | |
|                        TABSTRACTPROCDEF
 | |
| ***************************************************************************}
 | |
| 
 | |
|     procedure disposepdefcoll(var para1 : pdefcoll);
 | |
|       var
 | |
|          hp : pdefcoll;
 | |
|       begin
 | |
|          hp:=para1;
 | |
|          while assigned(hp) do
 | |
|            begin
 | |
|               para1:=hp^.next;
 | |
|               dispose(hp);
 | |
|               hp:=para1;
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tabstractprocdef.init;
 | |
|       begin
 | |
|          inherited init;
 | |
|          para1:=nil;
 | |
|          fpu_used:=0;
 | |
|          proctypeoption:=potype_none;
 | |
|          proccalloptions:=[];
 | |
|          procoptions:=[];
 | |
|          retdef:=voiddef;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     destructor tabstractprocdef.done;
 | |
|       begin
 | |
|          disposepdefcoll(para1);
 | |
|          inherited done;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
 | |
|       var
 | |
|          hp : pdefcoll;
 | |
|       begin
 | |
|          new(hp);
 | |
|          hp^.paratyp:=vsp;
 | |
|          hp^.datasym:=nil;
 | |
|          hp^.data:=p;
 | |
|          hp^.next:=para1;
 | |
|          hp^.register:=R_NO;
 | |
|          para1:=hp;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tabstractprocdef.concattypesym(p : ptypesym;vsp : tvarspez);
 | |
|       var
 | |
|          hp : pdefcoll;
 | |
|       begin
 | |
|          new(hp);
 | |
|          hp^.paratyp:=vsp;
 | |
|          hp^.datasym:=p;
 | |
|          hp^.data:=p^.definition;
 | |
|          hp^.next:=para1;
 | |
|          hp^.register:=R_NO;
 | |
|          para1:=hp;
 | |
|       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(retdef) and is_fpu(retdef) then
 | |
|            fpu_used:=2;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tabstractprocdef.deref;
 | |
|       var
 | |
|          hp : pdefcoll;
 | |
|       begin
 | |
|          inherited deref;
 | |
|          resolvedef(retdef);
 | |
|          hp:=para1;
 | |
|          while assigned(hp) do
 | |
|            begin
 | |
|               if assigned(hp^.datasym) then
 | |
|                begin
 | |
|                  resolvesym(psym(hp^.datasym));
 | |
|                  hp^.data:=hp^.datasym^.definition;
 | |
|                end
 | |
|               else
 | |
|                resolvedef(hp^.data);
 | |
|               hp:=hp^.next;
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tabstractprocdef.load;
 | |
|       var
 | |
|          last,hp : pdefcoll;
 | |
|          count,i : word;
 | |
|       begin
 | |
|          inherited load;
 | |
|          retdef:=readdefref;
 | |
|          fpu_used:=readbyte;
 | |
|          proctypeoption:=tproctypeoption(readlong);
 | |
|          readsmallset(proccalloptions);
 | |
|          readsmallset(procoptions);
 | |
|          count:=readword;
 | |
|          para1:=nil;
 | |
|          savesize:=target_os.size_of_pointer;
 | |
|          for i:=1 to count do
 | |
|            begin
 | |
|               new(hp);
 | |
|               hp^.paratyp:=tvarspez(readbyte);
 | |
|               { hp^.register:=tregister(readbyte); }
 | |
|               hp^.register:=R_NO;
 | |
|               hp^.data:=readdefref;
 | |
|               hp^.datasym:=ptypesym(readsymref);
 | |
|               hp^.next:=nil;
 | |
|               if para1=nil then
 | |
|                 para1:=hp
 | |
|               else
 | |
|                 last^.next:=hp;
 | |
|               last:=hp;
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tabstractprocdef.write;
 | |
|       var
 | |
|          count : word;
 | |
|          hp : pdefcoll;
 | |
|       begin
 | |
|          inherited write;
 | |
|          writedefref(retdef);
 | |
|          current_ppu^.do_interface_crc:=false;
 | |
|          writebyte(fpu_used);
 | |
|          writelong(ord(proctypeoption));
 | |
|          writesmallset(proccalloptions);
 | |
|          writesmallset(procoptions);
 | |
|          hp:=para1;
 | |
|          count:=0;
 | |
|          while assigned(hp) do
 | |
|            begin
 | |
|               inc(count);
 | |
|               hp:=hp^.next;
 | |
|            end;
 | |
|          writeword(count);
 | |
|          hp:=para1;
 | |
|          while assigned(hp) do
 | |
|            begin
 | |
|               writebyte(byte(hp^.paratyp));
 | |
|               { writebyte(byte(hp^.register)); }
 | |
|               if assigned(hp^.datasym) then
 | |
|                begin
 | |
|                  writedefref(nil);
 | |
|                  writesymref(psym(hp^.datasym));
 | |
|                end
 | |
|               else
 | |
|                begin
 | |
|                  writedefref(hp^.data);
 | |
|                  writesymref(nil);
 | |
|                end;
 | |
|               hp:=hp^.next;
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tabstractprocdef.para_size : longint;
 | |
|       var
 | |
|          pdc : pdefcoll;
 | |
|          l : longint;
 | |
|       begin
 | |
|          l:=0;
 | |
|          pdc:=para1;
 | |
|          while assigned(pdc) do
 | |
|           begin
 | |
|             case pdc^.paratyp of
 | |
|               vs_var   : inc(l,target_os.size_of_pointer);
 | |
|               vs_value,
 | |
|               vs_const : if push_addr_param(pdc^.data) then
 | |
|                           inc(l,target_os.size_of_pointer)
 | |
|                          else
 | |
|                           inc(l,align(pdc^.data^.size,target_os.stackalignment));
 | |
|             end;
 | |
|             pdc:=pdc^.next;
 | |
|           end;
 | |
|          para_size:=l;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tabstractprocdef.demangled_paras : string;
 | |
| 
 | |
|       var s : string;
 | |
| 
 | |
|       procedure doconcat(p : pdefcoll);
 | |
| 
 | |
|         begin
 | |
|            if assigned(p^.next) then
 | |
|              doconcat(p^.next)
 | |
|            else
 | |
|              s:='(';
 | |
|            if assigned(p^.data^.sym) then
 | |
|              s:=s+p^.data^.sym^.name
 | |
|            else if p^.paratyp=vs_var then
 | |
|              s:=s+'var'
 | |
|            else if p^.paratyp=vs_const then
 | |
|              s:=s+'const';
 | |
|            if p<>para1 then
 | |
|              s:=s+','
 | |
|            else
 | |
|              s:=s+')';
 | |
|         end;
 | |
| 
 | |
|       begin
 | |
|         s:='';
 | |
|         { a recursive solution is the easiest way to inverse the parameter }
 | |
|         { collection                                                       }
 | |
|         if assigned(para1) then
 | |
|           doconcat(para1);
 | |
|         demangled_paras:=s;
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     function tabstractprocdef.stabstring : pchar;
 | |
|       begin
 | |
|         stabstring := strpnew('abstractproc'+numberstring+';');
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
 | |
|       begin
 | |
|          if (not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
 | |
|             and not is_def_stab_written then
 | |
|            begin
 | |
|               if assigned(retdef) then forcestabto(asmlist,retdef);
 | |
|               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}
 | |
| {$ifdef alpha}
 | |
|          usedregisters_int:=$ffffffff;
 | |
|          usedregisters_fpu:=$ffffffff;
 | |
| {$endif alpha}
 | |
| {$endif newcg}
 | |
|          forwarddef:=true;
 | |
|          interfacedef:=false;
 | |
|          _class := nil;
 | |
|          code:=nil;
 | |
|          count:=false;
 | |
|          is_used:=false;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     constructor tprocdef.load;
 | |
|       var
 | |
|          s : string;
 | |
|       begin
 | |
|          inherited load;
 | |
|          deftype:=procdef;
 | |
| 
 | |
| {$ifdef newcg}
 | |
|          readnormalset(usedregisters);
 | |
| {$else newcg}
 | |
| {$ifdef i386}
 | |
|          usedregisters:=readbyte;
 | |
| {$endif i386}
 | |
| {$ifdef m68k}
 | |
|          usedregisters:=readword;
 | |
| {$endif}
 | |
| {$ifdef alpha}
 | |
|          usedregisters_int:=readlong;
 | |
|          usedregisters_fpu:=readlong;
 | |
| {$endif alpha}
 | |
| {$endif newcg}
 | |
|          s:=readstring;
 | |
|          setstring(_mangledname,s);
 | |
| 
 | |
|          extnumber:=readlong;
 | |
|          nextoverloaded:=pprocdef(readdefref);
 | |
|          _class := pobjectdef(readdefref);
 | |
|          readposinfo(fileinfo);
 | |
| 
 | |
|          if (cs_link_deffile in aktglobalswitches) and
 | |
|             (tf_need_export in target_info.flags) and
 | |
|             (po_exports in procoptions) then
 | |
|            deffile.AddExport(mangledname);
 | |
| 
 | |
|          parast:=nil;
 | |
|          localst:=nil;
 | |
|          forwarddef:=false;
 | |
|          interfacedef:=false;
 | |
|          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}
 | |
|         pdo : pobjectdef;
 | |
| {$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}
 | |
|              pdo:=_class;
 | |
|              new(parast,loadas(parasymtable));
 | |
|              parast^.next:=owner;
 | |
|              parast^.load_browser;
 | |
|              new(localst,loadas(localsymtable));
 | |
|              localst^.next:=parast;
 | |
|              localst^.load_browser;
 | |
| {$endif ndef NOLOCALBROWSER}
 | |
|           end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tprocdef.write_references : boolean;
 | |
|       var
 | |
|         ref : pref;
 | |
| {$ifndef NOLOCALBROWSER}
 | |
|         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^.writeas;
 | |
|              parast^.unitid:=local_symtable_index;
 | |
|              inc(local_symtable_index);
 | |
|              parast^.write_browser;
 | |
|              if not assigned(localst) then
 | |
|                localst:=new(psymtable,init(localsymtable));
 | |
|              localst^.writeas;
 | |
|              localst^.unitid:=local_symtable_index;
 | |
|              inc(local_symtable_index);
 | |
|              localst^.write_browser;
 | |
|              { 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
 | |
|            dispose(defref,done);
 | |
|          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
 | |
|            disposetree(ptree(code));
 | |
|          if (po_msgstr in procoptions) then
 | |
|            strdispose(messageinf.str);
 | |
|          if
 | |
| {$ifdef tp}
 | |
|          not(use_big) and
 | |
| {$endif}
 | |
|            assigned(_mangledname) then
 | |
|            globals.strdispose(_mangledname);
 | |
|          inherited done;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tprocdef.write;
 | |
|       begin
 | |
|          inherited write;
 | |
|          current_ppu^.do_interface_crc:=false;
 | |
| {$ifdef newcg}
 | |
|          writenormalset(usedregisters);
 | |
| {$else newcg}
 | |
| {$ifdef i386}
 | |
|          writebyte(usedregisters);
 | |
| {$endif i386}
 | |
| {$ifdef m68k}
 | |
|          writeword(usedregisters);
 | |
| {$endif}
 | |
| {$ifdef alpha}
 | |
|          writelong(usedregisters_int);
 | |
|          writelong(usedregisters_fpu);
 | |
| {$endif alpha}
 | |
| {$endif newcg}
 | |
|          writestring(mangledname);
 | |
|          current_ppu^.do_interface_crc:=true;
 | |
|          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);
 | |
|          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);
 | |
|       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)^.definition^.numberstring+','+vs+';');
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tprocdef.stabstring : pchar;
 | |
|       var param : pdefcoll;
 | |
|           i : word;
 | |
|           oldrec : pchar;
 | |
|       begin
 | |
|       oldrec := stabrecstring;
 | |
|       getmem(StabRecString,1024);
 | |
|       param := para1;
 | |
|       i := 0;
 | |
|       while assigned(param) do
 | |
|         begin
 | |
|            inc(i);
 | |
|            param := param^.next;
 | |
|         end;
 | |
|       strpcopy(StabRecString,'f'+retdef^.numberstring);
 | |
|       if i>0 then
 | |
|         begin
 | |
|         strpcopy(strend(StabRecString),','+tostr(i)+';');
 | |
|         (* confuse gdb !! PM
 | |
|         if assigned(parast) then
 | |
|           parast^.foreach({$ifndef TP}@{$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^.data^.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;
 | |
|       begin
 | |
|          inherited deref;
 | |
|          resolvedef(pdef(nextoverloaded));
 | |
|          resolvedef(pdef(_class));
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tprocdef.mangledname : string;
 | |
| {$ifdef tp}
 | |
|       var
 | |
|          oldpos : longint;
 | |
|          s : string;
 | |
|          b : byte;
 | |
| {$endif tp}
 | |
|       begin
 | |
| {$ifndef Delphi}
 | |
| {$ifdef tp}
 | |
|          if use_big then
 | |
|            begin
 | |
|               symbolstream.seek(longint(_mangledname));
 | |
|               symbolstream.read(b,1);
 | |
|               symbolstream.read(s[1],b);
 | |
|               s[0]:=chr(b);
 | |
|               mangledname:=s;
 | |
|            end
 | |
|          else
 | |
| {$endif}
 | |
| {$endif Delphi}
 | |
|           mangledname:=strpas(_mangledname);
 | |
|          if count then
 | |
|            is_used:=true;
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$IfDef GDB}
 | |
|     function tprocdef.cplusplusmangledname : string;
 | |
|       var
 | |
|          s,s2 : string;
 | |
|          param : pdefcoll;
 | |
|       begin
 | |
|       s := sym^.name;
 | |
|       if _class <> nil then
 | |
|         begin
 | |
|         s2 := _class^.objname^;
 | |
|         s := s+'__'+tostr(length(s2))+s2;
 | |
|         end else s := s + '_';
 | |
|       param := para1;
 | |
|       while assigned(param) do
 | |
|         begin
 | |
|         s2 := param^.data^.sym^.name;
 | |
|         s := s+tostr(length(s2))+s2;
 | |
|         param := param^.next;
 | |
|         end;
 | |
|       cplusplusmangledname:=s;
 | |
|       end;
 | |
| {$EndIf GDB}
 | |
| 
 | |
| 
 | |
|     procedure tprocdef.setmangledname(const s : string);
 | |
|       begin
 | |
|          if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
 | |
|            strdispose(_mangledname);
 | |
|          setstring(_mangledname,s);
 | |
|          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;
 | |
|       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(retdef) 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 : word;
 | |
|          param : pdefcoll;
 | |
|       begin
 | |
|         i := 0;
 | |
|         param := para1;
 | |
|         while assigned(param) do
 | |
|           begin
 | |
|           inc(i);
 | |
|           param := param^.next;
 | |
|           end;
 | |
|         getmem(nss,1024);
 | |
|         { it is not a function but a function pointer !! (PM) }
 | |
| 
 | |
|         strpcopy(nss,'*f'+retdef^.numberstring{+','+tostr(i)}+';');
 | |
|         param := para1;
 | |
|         i := 0;
 | |
|         { 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 }
 | |
|         (* 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 !!}
 | |
|           pst := strpnew('p'+tostr(i)+':'+param^.data^.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(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
 | |
|            and not is_def_stab_written then
 | |
|            inherited concatstabto(asmlist);
 | |
|          is_def_stab_written:=true;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
| 
 | |
|     procedure tprocvardef.write_rtti_data;
 | |
|       begin
 | |
|          {!!!!!!!}
 | |
|       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(retdef) then
 | |
|            gettypename:='<procedure variable type of function'+demangled_paras+':'+retdef^.gettypename+'>'
 | |
|          else
 | |
|            gettypename:='<procedure variable type of procedure'+demangled_paras+'>';
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {***************************************************************************
 | |
|                               TOBJECTDEF
 | |
| ***************************************************************************}
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     const
 | |
|        vtabletype : word = 0;
 | |
|        vtableassigned : boolean = false;
 | |
| {$endif GDB}
 | |
| 
 | |
|    constructor tobjectdef.init(const n : string;c : pobjectdef);
 | |
|      begin
 | |
|         tdef.init;
 | |
|         deftype:=objectdef;
 | |
|         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);
 | |
|      end;
 | |
| 
 | |
| 
 | |
|     constructor tobjectdef.load;
 | |
|       var
 | |
|          oldread_member : boolean;
 | |
|       begin
 | |
|          tdef.load;
 | |
|          deftype:=objectdef;
 | |
|          savesize:=readlong;
 | |
|          vmt_offset:=readlong;
 | |
|          objname:=stringdup(readstring);
 | |
|          childof:=pobjectdef(readdefref);
 | |
|          readsmallset(objectoptions);
 | |
|          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
 | |
|             is_class and
 | |
|             (objname^='TOBJECT') then
 | |
|            class_tobject:=@self;
 | |
|          has_rtti:=true;
 | |
|        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);
 | |
|         tdef.done;
 | |
|      end;
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.write;
 | |
|       var
 | |
|          oldread_member : boolean;
 | |
|       begin
 | |
|          tdef.write;
 | |
|          writelong(size);
 | |
|          writelong(vmt_offset);
 | |
|          writestring(objname^);
 | |
|          writedefref(childof);
 | |
|          writesmallset(objectoptions);
 | |
|          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
 | |
|          resolvedef(pdef(childof));
 | |
|          oldrecsyms:=aktrecordsymtable;
 | |
|          aktrecordsymtable:=symtable;
 | |
|          symtable^.deref;
 | |
|          aktrecordsymtable:=oldrecsyms;
 | |
|       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
 | |
|              objectoptions:=objectoptions+(c^.objectoptions*
 | |
|                [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
 | |
|                begin
 | |
|                   vmt_offset:=c^.vmt_offset;
 | |
| {$ifdef INCLUDEOK}
 | |
|                   include(objectoptions,oo_has_vmt);
 | |
| {$else}
 | |
|                   objectoptions:=objectoptions+[oo_has_vmt];
 | |
| {$endif}
 | |
|                end;
 | |
|           end;
 | |
|         savesize := symtable^.datasize;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|    procedure tobjectdef.insertvmt;
 | |
|      begin
 | |
|         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);
 | |
| {$ifdef INCLUDEOK}
 | |
|              include(objectoptions,oo_has_vmt);
 | |
| {$else}
 | |
|              objectoptions:=objectoptions+[oo_has_vmt];
 | |
| {$endif}
 | |
|           end;
 | |
|      end;
 | |
| 
 | |
| 
 | |
|    procedure tobjectdef.check_forwards;
 | |
|      begin
 | |
|         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^);
 | |
| {$ifdef INCLUDEOK}
 | |
|              exclude(objectoptions,oo_is_forward);
 | |
| {$else}
 | |
|              objectoptions:=objectoptions-[oo_is_forward];
 | |
| {$endif}
 | |
|           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;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.size : longint;
 | |
|       begin
 | |
|         if (oo_is_class in objectoptions) then
 | |
|           size:=target_os.size_of_pointer
 | |
|         else
 | |
|           size:=symtable^.datasize;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.alignment:longint;
 | |
|       begin
 | |
|         alignment:=symtable^.dataalignment;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.vmt_mangledname : string;
 | |
|     {DM: I get a nil pointer on the owner name. I don't know if this
 | |
|      mayhappen, 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:=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:=objname^;
 | |
|        rtti_name:='RTTI_'+s1+'$_'+s2;
 | |
|     end;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.is_class : boolean;
 | |
|       begin
 | |
|          is_class:=(oo_is_class in objectoptions);
 | |
|       end;
 | |
| 
 | |
| 
 | |
| {$ifdef GDB}
 | |
|     procedure addprocname(p :pnamedindexobject);
 | |
|     var virtualind,argnames : string;
 | |
|         news, newrec : pchar;
 | |
|         pd,ipd : pprocdef;
 | |
|         lindex : longint;
 | |
|         para : pdefcoll;
 | |
|         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^.numberstring+';'
 | |
|                    end else virtualind := '.';
 | |
|                 { arguments are not listed here }
 | |
|                 {we don't need another definition}
 | |
|                  para := pd^.para1;
 | |
|                  { 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 := '';
 | |
| 
 | |
|                  while assigned(para) do
 | |
|                    begin
 | |
|                    if para^.data^.deftype = formaldef then
 | |
|                      begin
 | |
|                         if para^.paratyp=vs_var then
 | |
|                           argnames := argnames+'3var'
 | |
|                         else if para^.paratyp=vs_const then
 | |
|                           argnames:=argnames+'5const';
 | |
|                      end
 | |
|                    else
 | |
|                      begin
 | |
|                      { if the arg definition is like (v: ^byte;..
 | |
|                      there is no sym attached to data !!! }
 | |
|                      if assigned(para^.data^.sym) then
 | |
|                        begin
 | |
|                           arglength := length(para^.data^.sym^.name);
 | |
|                           argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
 | |
|                        end
 | |
|                      else
 | |
|                        begin
 | |
|                           argnames:=argnames+'11unnamedtype';
 | |
|                        end;
 | |
|                      end;
 | |
|                    para := para^.next;
 | |
|                    end;
 | |
|                 ipd^.is_def_stab_written := true;
 | |
|                 { 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^.retdef^.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;
 | |
|           oldrecsize : longint;
 | |
|           str_end : string;
 | |
|       begin
 | |
|         oldrec := stabrecstring;
 | |
|         oldrecsize:=stabrecsize;
 | |
|         stabrecsize:=memsizeinc;
 | |
|         GetMem(stabrecstring,stabrecsize);
 | |
|         strpcopy(stabRecString,'s'+tostr(size));
 | |
|         if assigned(childof) then
 | |
|           {only one ancestor not virtual, public, at base offset 0 }
 | |
|           {       !1           ,    0       2         0    ,       }
 | |
|           strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
 | |
|         {virtual table to implement yet}
 | |
|         RecOffset := 0;
 | |
|         symtable^.foreach({$ifndef TP}@{$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'+numberstring+':'+typeglobalnumber('vtblarray')
 | |
|                 +','+tostr(vmt_offset*8)+';');
 | |
|            end;
 | |
|         symtable^.foreach({$ifndef TP}@{$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;
 | |
|              str_end:=';~%'+anc^.numberstring+';';
 | |
|           end
 | |
|         else
 | |
|           str_end:=';';
 | |
|         strpcopy(strend(stabrecstring),str_end);
 | |
|         stabstring := strnew(StabRecString);
 | |
|         freemem(stabrecstring,stabrecsize);
 | |
|         stabrecstring := oldrec;
 | |
|         stabrecsize:=oldrecsize;
 | |
|       end;
 | |
| {$endif GDB}
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.write_child_init_data;
 | |
|       begin
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.write_init_data;
 | |
|       begin
 | |
|          if is_class then
 | |
|            rttilist^.concat(new(pai_const,init_8bit(tkclass)))
 | |
|          else
 | |
|            rttilist^.concat(new(pai_const,init_8bit(tkobject)));
 | |
| 
 | |
|          { 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;
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
 | |
|          rttilist^.concat(new(pai_const,init_32bit(count)));
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.needs_inittable : boolean;
 | |
|       var
 | |
|          oldb : boolean;
 | |
|       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({$ifndef TP}@{$endif}check_rec_inittable);
 | |
|          needs_inittable:=binittable;
 | |
|          binittable:=oldb;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure count_published_properties(sym:pnamedindexobject);
 | |
|       {$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          if (psym(sym)^.typ=propertysym) and
 | |
|             (sp_published in psym(sym)^.symoptions) then
 | |
|            inc(count);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure write_property_info(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       var
 | |
|          proctypesinfo : byte;
 | |
| 
 | |
|       procedure writeproc(sym : psym;def : pdef;shiftvalue : byte);
 | |
|         var
 | |
|            typvalue : byte;
 | |
|         begin
 | |
|            if not(assigned(sym)) then
 | |
|              begin
 | |
|                 rttilist^.concat(new(pai_const,init_32bit(1)));
 | |
|                 typvalue:=3;
 | |
|              end
 | |
|            else if sym^.typ=varsym then
 | |
|              begin
 | |
|                 rttilist^.concat(new(pai_const,init_32bit(
 | |
|                   pvarsym(sym)^.address)));
 | |
|                 typvalue:=0;
 | |
|              end
 | |
|            else
 | |
|              begin
 | |
|                 if not(po_virtualmethod in pprocdef(def)^.procoptions) then
 | |
|                   begin
 | |
|                      rttilist^.concat(new(pai_const_symbol,initname(pprocdef(def)^.mangledname)));
 | |
|                      typvalue:=1;
 | |
|                   end
 | |
|                 else
 | |
|                   begin
 | |
|                      { virtual method, write vmt offset }
 | |
|                      rttilist^.concat(new(pai_const,init_32bit(pprocdef(def)^.extnumber*4+12)));
 | |
|                      typvalue:=2;
 | |
|                   end;
 | |
|              end;
 | |
|            proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
 | |
|         end;
 | |
| 
 | |
|       begin
 | |
| 
 | |
|          if (psym(sym)^.typ=propertysym) and
 | |
|             (ppo_indexed in ppropertysym(sym)^.propoptions) then
 | |
|            proctypesinfo:=$40
 | |
|          else
 | |
|            proctypesinfo:=0;
 | |
|          if (psym(sym)^.typ=propertysym) and
 | |
|             (sp_published in psym(sym)^.symoptions) then
 | |
|            begin
 | |
|               rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype^.get_rtti_label)));
 | |
|               writeproc(ppropertysym(sym)^.readaccesssym,ppropertysym(sym)^.readaccessdef,0);
 | |
|               writeproc(ppropertysym(sym)^.writeaccesssym,ppropertysym(sym)^.writeaccessdef,2);
 | |
|               { isn't it stored ? }
 | |
|               if not(ppo_stored in ppropertysym(sym)^.propoptions) then
 | |
|                 begin
 | |
|                    rttilist^.concat(new(pai_const,init_32bit(1)));
 | |
|                    proctypesinfo:=proctypesinfo or (3 shl 4);
 | |
|                 end
 | |
|               else
 | |
|                 writeproc(ppropertysym(sym)^.storedsym,ppropertysym(sym)^.storeddef,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)^.name))));
 | |
|               rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
 | |
|            end;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure generate_published_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
 | |
|       begin
 | |
|          if (psym(sym)^.typ=propertysym) and
 | |
|             (sp_published in psym(sym)^.symoptions) then
 | |
|            ppropertysym(sym)^.proptype^.get_rtti_label;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.write_child_rtti_data;
 | |
|       begin
 | |
|          symtable^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.generate_rtti;
 | |
|       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;
 | |
| 
 | |
| 
 | |
|     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({$ifndef TP}@{$endif}count_published_properties);
 | |
|          next_free_name_index:=i+count;
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     procedure tobjectdef.write_rtti_data;
 | |
|       begin
 | |
|          if is_class then
 | |
|            rttilist^.concat(new(pai_const,init_8bit(tkclass)))
 | |
|          else
 | |
|            rttilist^.concat(new(pai_const,init_8bit(tkobject)));
 | |
| 
 | |
|          { generate the name }
 | |
|          rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
 | |
|          rttilist^.concat(new(pai_string,init(objname^)));
 | |
| 
 | |
|          { write class type }
 | |
|          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({$ifndef TP}@{$endif}count_published_properties);
 | |
|          rttilist^.concat(new(pai_const,init_16bit(count)));
 | |
| 
 | |
|          { write unit name }
 | |
|          if assigned(owner^.name) then
 | |
|            begin
 | |
|               rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
 | |
|               rttilist^.concat(new(pai_string,init(owner^.name^)));
 | |
|            end
 | |
|          else
 | |
|            rttilist^.concat(new(pai_const,init_8bit(0)));
 | |
| 
 | |
|          { write published properties count }
 | |
|          count:=0;
 | |
|          symtable^.foreach({$ifndef TP}@{$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({$ifndef TP}@{$endif}write_property_info);
 | |
|       end;
 | |
| 
 | |
| 
 | |
|     function tobjectdef.is_publishable : boolean;
 | |
|       begin
 | |
|          is_publishable:=is_class;
 | |
|       end;
 | |
| 
 | |
|     function  tobjectdef.get_rtti_label : string;
 | |
| 
 | |
|       begin
 | |
|          get_rtti_label:=rtti_name;
 | |
|       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.139  1999-08-03 22:03:14  peter
 | |
|     * moved bitmask constants to sets
 | |
|     * some other type/const renamings
 | |
| 
 | |
|   Revision 1.138  1999/08/02 21:29:02  florian
 | |
|     * the main branch psub.pas is now used for
 | |
|       newcg compiler
 | |
| 
 | |
|   Revision 1.137  1999/07/31 22:37:17  michael
 | |
|   * Fix of initialization information generation
 | |
| 
 | |
|   Revision 1.136  1999/07/29 20:54:07  peter
 | |
|     * write .size also
 | |
| 
 | |
|   Revision 1.135  1999/07/27 23:42:18  peter
 | |
|     * indirect type referencing is now allowed
 | |
| 
 | |
|   Revision 1.134  1999/07/23 23:07:03  peter
 | |
|     * fixed stabs for record which still used savesize
 | |
| 
 | |
|   Revision 1.133  1999/07/23 16:05:28  peter
 | |
|     * alignment is now saved in the symtable
 | |
|     * C alignment added for records
 | |
|     * PPU version increased to solve .12 <-> .13 probs
 | |
| 
 | |
|   Revision 1.132  1999/07/18 14:47:32  florian
 | |
|     * bug 487 fixed, (inc(<property>) isn't allowed)
 | |
|     * more fixes to compile with Delphi
 | |
| 
 | |
|   Revision 1.131  1999/07/06 21:48:27  florian
 | |
|     * a lot bug fixes:
 | |
|        - po_external isn't any longer necessary for procedure compatibility
 | |
|        - m_tp_procvar is in -Sd now available
 | |
|        - error messages of procedure variables improved
 | |
|        - return values with init./finalization fixed
 | |
|        - data types with init./finalization aren't any longer allowed in variant
 | |
|          record
 | |
| 
 | |
|   Revision 1.130  1999/06/22 16:24:44  pierre
 | |
|    * local browser stuff corrected
 | |
| 
 | |
|   Revision 1.129  1999/06/02 22:44:21  pierre
 | |
|    * previous wrong log corrected
 | |
| 
 | |
|   Revision 1.128  1999/06/02 22:25:52  pierre
 | |
|   * changed $ifdef FPC @ into $ifndef TP
 | |
| 
 | |
|   Revision 1.127  1999/06/02 10:26:50  florian
 | |
|     * corrected order of parameter type for -vb
 | |
| 
 | |
|   Revision 1.126  1999/06/02 10:11:50  florian
 | |
|     * make cycle fixed i.e. compilation with 0.99.10
 | |
|     * some fixes for qword
 | |
|     * start of register calling conventions
 | |
| 
 | |
|   Revision 1.125  1999/06/01 14:45:56  peter
 | |
|     * @procvar is now always needed for FPC
 | |
| 
 | |
|   Revision 1.124  1999/05/31 16:42:33  peter
 | |
|     * interfacedef flag for procdef if it's defined in the interface, to
 | |
|       make a difference with 'forward;' directive forwarddef. Fixes 253
 | |
| 
 | |
|   Revision 1.123  1999/05/27 19:45:02  peter
 | |
|     * removed oldasm
 | |
|     * plabel -> pasmlabel
 | |
|     * -a switches to source writing automaticly
 | |
|     * assembler readers OOPed
 | |
|     * asmsymbol automaticly external
 | |
|     * jumptables and other label fixes for asm readers
 | |
| 
 | |
|   Revision 1.122  1999/05/23 18:42:14  florian
 | |
|     * better error recovering in typed constants
 | |
|     * some problems with arrays of const fixed, some problems
 | |
|       due my previous
 | |
|        - the location type of array constructor is now LOC_MEM
 | |
|        - the pushing of high fixed
 | |
|        - parameter copying fixed
 | |
|        - zero temp. allocation removed
 | |
|     * small problem in the assembler writers fixed:
 | |
|       ref to nil wasn't written correctly
 | |
| 
 | |
|   Revision 1.121  1999/05/21 13:55:19  peter
 | |
|     * NEWLAB for label as symbol
 | |
| 
 | |
|   Revision 1.120  1999/05/20 22:22:43  pierre
 | |
|     + added synonym filed for ttypesym
 | |
|       allows a clean disposal of tdefs and related ttypesyms
 | |
| 
 | |
|   Revision 1.119  1999/05/19 16:48:26  florian
 | |
|     * tdef.typename: returns a now a proper type name for the most types
 | |
| 
 | |
|   Revision 1.118  1999/05/19 12:08:11  florian
 | |
|     * tobject wasn't set as default anchestor, was a problem with the new ppu
 | |
|       handling
 | |
| 
 | |
|   Revision 1.117  1999/05/17 21:57:15  florian
 | |
|     * new temporary ansistring handling
 | |
| 
 | |
|   Revision 1.116  1999/05/16 02:26:51  peter
 | |
|     * fixed loading of classrefdef
 | |
| 
 | |
|   Revision 1.115  1999/05/14 17:52:26  peter
 | |
|     * new deref code
 | |
| 
 | |
|   Revision 1.114  1999/05/13 21:59:41  peter
 | |
|     * removed oldppu code
 | |
|     * warning if objpas is loaded from uses
 | |
|     * first things for new deref writing
 | |
| 
 | |
|   Revision 1.113  1999/05/12 00:19:58  peter
 | |
|     * removed R_DEFAULT_SEG
 | |
|     * uniform float names
 | |
| 
 | |
|   Revision 1.112  1999/05/08 19:52:35  peter
 | |
|     + MessagePos() which is enhanced Message() function but also gets the
 | |
|       position info
 | |
|     * Removed comp warnings
 | |
| 
 | |
|   Revision 1.111  1999/05/07 11:06:37  florian
 | |
|     * enumeration type names are now written in lowercase (rtti)
 | |
| 
 | |
|   Revision 1.110  1999/05/06 09:05:28  peter
 | |
|     * generic write_float and str_float
 | |
|     * fixed constant float conversions
 | |
| 
 | |
|   Revision 1.109  1999/05/05 10:05:56  florian
 | |
|     * a delphi compiled compiler recompiles ppc
 | |
| 
 | |
|   Revision 1.108  1999/04/28 22:30:52  pierre
 | |
|    * delete -> deleteindex in tdef.correct_owner_symtable
 | |
| 
 | |
|   Revision 1.107  1999/04/28 06:02:11  florian
 | |
|     * changes of Bruessel:
 | |
|        + message handler can now take an explicit self
 | |
|        * typinfo fixed: sometimes the type names weren't written
 | |
|        * the type checking for pointer comparisations and subtraction
 | |
|          and are now more strict (was also buggy)
 | |
|        * small bug fix to link.pas to support compiling on another
 | |
|          drive
 | |
|        * probable bug in popt386 fixed: call/jmp => push/jmp
 | |
|          transformation didn't count correctly the jmp references
 | |
|        + threadvar support
 | |
|        * warning if ln/sqrt gets an invalid constant argument
 | |
| 
 | |
|   Revision 1.106  1999/04/26 18:30:01  peter
 | |
|     * farpointerdef moved into pointerdef.is_far
 | |
| 
 | |
|   Revision 1.105  1999/04/26 13:31:47  peter
 | |
|     * release storenumber,double_checksum
 | |
| 
 | |
|   Revision 1.104  1999/04/21 09:43:50  peter
 | |
|     * storenumber works
 | |
|     * fixed some typos in double_checksum
 | |
|     + incompatible types type1 and type2 message (with storenumber)
 | |
| 
 | |
|   Revision 1.103  1999/04/19 09:28:20  peter
 | |
|     * fixed crash when writing overload operator to ppu
 | |
| 
 | |
|   Revision 1.102  1999/04/17 22:01:28  pierre
 | |
|    * typo error fix in STORENUMBER code
 | |
| 
 | |
|   Revision 1.101  1999/04/14 09:14:58  peter
 | |
|     * first things to store the symbol/def number in the ppu
 | |
| 
 | |
|   Revision 1.100  1999/04/08 15:57:51  peter
 | |
|     + subrange checking for readln()
 | |
| 
 | |
|   Revision 1.99  1999/04/07 15:39:32  pierre
 | |
|     + double_checksum code added
 | |
| 
 | |
|   Revision 1.98  1999/03/06 17:24:16  peter
 | |
|     * reset savesize in tdef.init
 | |
| 
 | |
|   Revision 1.97  1999/03/01 13:45:04  pierre
 | |
|    + added staticppusymtable symtable type for local browsing
 | |
| 
 | |
|   Revision 1.96  1999/02/25 21:02:52  peter
 | |
|     * ag386bin updates
 | |
|     + coff writer
 | |
| 
 | |
|   Revision 1.95  1999/02/23 18:29:23  pierre
 | |
|     * win32 compilation error fix
 | |
|     + some work for local browser (not cl=omplete yet)
 | |
| 
 | |
|   Revision 1.94  1999/02/22 20:13:38  florian
 | |
|     + first implementation of message keyword
 | |
| 
 | |
|   Revision 1.93  1999/02/22 13:07:07  pierre
 | |
|     + -b and -bl options work !
 | |
|     + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
 | |
|       is not enabled when quitting global section
 | |
|     * local vars and procedures are not yet stored into PPU
 | |
| 
 | |
|   Revision 1.92  1999/02/17 10:14:20  peter
 | |
|     * set the first enumsym also for subrange types
 | |
| 
 | |
|   Revision 1.91  1999/02/08 09:51:21  pierre
 | |
|    * gdb info for local functions was wrong
 | |
| 
 | |
|   Revision 1.90  1999/01/26 09:57:29  pierre
 | |
|    * open arrays stabs changed
 | |
| 
 | |
|   Revision 1.89  1999/01/22 17:29:30  pierre
 | |
|    * overflow in addname for open arrays removed
 | |
| 
 | |
|   Revision 1.88  1999/01/20 14:18:39  pierre
 | |
|     * bugs related to mangledname solved
 | |
|       - linux external without name
 | |
|       -external procs already used
 | |
|       (added count and is_used boolean fiels in tprocvar)
 | |
| 
 | |
|   Revision 1.87  1999/01/19 10:56:05  pierre
 | |
|    typeof(object) without vmt generates an error instead of an internalerror
 | |
| 
 | |
|   Revision 1.86  1999/01/12 14:25:32  peter
 | |
|     + BrowserLog for browser.log generation
 | |
|     + BrowserCol for browser info in TCollections
 | |
|     * released all other UseBrowser
 | |
| 
 | |
|   Revision 1.85  1998/12/30 22:15:52  peter
 | |
|     + farpointer type
 | |
|     * absolutesym now also stores if its far
 | |
| 
 | |
|   Revision 1.84  1998/12/30 13:41:12  peter
 | |
|     * released valuepara
 | |
| 
 | |
|   Revision 1.83  1998/12/21 14:03:08  pierre
 | |
|    * procvar stabs correction
 | |
| 
 | |
|   Revision 1.82  1998/12/19 00:23:52  florian
 | |
|     * ansistring memory leaks fixed
 | |
| 
 | |
|   Revision 1.81  1998/12/11 08:57:22  pierre
 | |
|    * internal gdb types for booleans and 64bit integers
 | |
| 
 | |
|   Revision 1.80  1998/12/10 09:47:26  florian
 | |
|     + basic operations with int64/qord (compiler with -dint64)
 | |
|     + rtti of enumerations extended: names are now written
 | |
| 
 | |
|   Revision 1.79  1998/12/08 10:18:12  peter
 | |
|     + -gh for heaptrc unit
 | |
| 
 | |
|   Revision 1.78  1998/12/08 09:06:30  pierre
 | |
|    + constructor destructor info for gdbpas
 | |
| 
 | |
|   Revision 1.77  1998/12/01 23:37:39  pierre
 | |
|    * function type problem for gdb fix
 | |
| 
 | |
|   Revision 1.76  1998/11/29 21:45:48  florian
 | |
|     * problem with arrays with init tables fixed
 | |
| 
 | |
|   Revision 1.75  1998/11/29 12:45:59  peter
 | |
|     * hack for arraydef.size overflow
 | |
| 
 | |
|   Revision 1.74  1998/11/27 14:50:47  peter
 | |
|     + open strings, $P switch support
 | |
| 
 | |
|   Revision 1.73  1998/11/26 14:47:00  michael
 | |
|   + Fixed RTTI constants
 | |
| 
 | |
|   Revision 1.72  1998/11/25 14:35:28  florian
 | |
|     * writting of rtti for properties fixed
 | |
| 
 | |
|   Revision 1.71  1998/11/20 15:35:59  florian
 | |
|     * problems with rtti fixed, hope it works
 | |
| 
 | |
|   Revision 1.70  1998/11/18 15:44:16  peter
 | |
|     * VALUEPARA for tp7 compatible value parameters
 | |
| 
 | |
|   Revision 1.69  1998/11/10 17:54:56  peter
 | |
|     * removed warning
 | |
| 
 | |
|   Revision 1.68  1998/11/05 23:34:36  peter
 | |
|     * don't dispose staticsymtable (caused crash under tp7 after a fatal
 | |
|       error)
 | |
| 
 | |
|   Revision 1.67  1998/11/05 12:02:56  peter
 | |
|     * released useansistring
 | |
|     * removed -Sv, its now available in fpc modes
 | |
| 
 | |
|   Revision 1.66  1998/10/26 22:58:22  florian
 | |
|     * new introduded problem with classes fix, the parent class wasn't set
 | |
|       correct, if the class was defined forward before
 | |
| 
 | |
|   Revision 1.65  1998/10/26 14:19:28  pierre
 | |
|     + added options -lS and -lT for source and target os output
 | |
|       (to have a easier way to test OS_SOURCE abd OS_TARGET in makefiles)
 | |
|     * several problems with rtti data
 | |
|       (type of sym was not checked)
 | |
|       assumed to be varsym when they could be procsym or property syms !!
 | |
| 
 | |
|   Revision 1.64  1998/10/22 17:11:21  pierre
 | |
|     + terminated the include exclude implementation for i386
 | |
|     * enums inside records fixed
 | |
| 
 | |
|   Revision 1.63  1998/10/20 09:32:56  peter
 | |
|     * removed some unused vars
 | |
| 
 | |
|   Revision 1.62  1998/10/20 08:06:58  pierre
 | |
|     * several memory corruptions due to double freemem solved
 | |
|       => never use p^.loc.location:=p^.left^.loc.location;
 | |
|     + finally I added now by default
 | |
|       that ra386dir translates global and unit symbols
 | |
|     + added a first field in tsymtable and
 | |
|       a nextsym field in tsym
 | |
|       (this allows to obtain ordered type info for
 | |
|       records and objects in gdb !)
 | |
| 
 | |
|   Revision 1.61  1998/10/19 08:55:05  pierre
 | |
|     * wrong stabs info corrected once again !!
 | |
|     + variable vmt offset with vmt field only if required
 | |
|       implemented now !!!
 | |
| 
 | |
|   Revision 1.60  1998/10/16 13:12:53  pierre
 | |
|     * added vmt_offsets in destructors code also !!!
 | |
|     * vmt_offset code for m68k
 | |
| 
 | |
|   Revision 1.59  1998/10/16 08:51:51  peter
 | |
|     + target_os.stackalignment
 | |
|     + stack can be aligned at 2 or 4 byte boundaries
 | |
| 
 | |
|   Revision 1.58  1998/10/15 15:13:30  pierre
 | |
|     + added oo_hasconstructor and oo_hasdestructor
 | |
|       for objects options
 | |
| 
 | |
|   Revision 1.57  1998/10/14 15:54:20  pierre
 | |
|     * smallsets are not entirely implemented for
 | |
|       m68k added a ifdef usesmallset
 | |
|       that is allways defined for i386
 | |
|       (enables testing for m68k)
 | |
| 
 | |
|   Revision 1.56  1998/10/09 11:47:56  pierre
 | |
|     * still more memory leaks fixes !!
 | |
| 
 | |
|   Revision 1.55  1998/10/06 17:16:55  pierre
 | |
|     * some memory leaks fixed (thanks to Peter for heaptrc !)
 | |
| 
 | |
|   Revision 1.54  1998/10/05 21:33:28  peter
 | |
|     * fixed 161,165,166,167,168
 | |
| 
 | |
|   Revision 1.53  1998/10/05 12:48:39  pierre
 | |
|     * wrong handling of range check for arrays fixed
 | |
| 
 | |
|   Revision 1.52  1998/10/02 07:20:38  florian
 | |
|     * range checking in units doesn't work if the units are smartlinked, fixed
 | |
| 
 | |
|   Revision 1.51  1998/09/25 12:01:41  florian
 | |
|     * tobjectdef.symtable.datasize was set to savesize, this is wrong now
 | |
|       because the symtable size is read from the ppu file
 | |
| 
 | |
|   Revision 1.50  1998/09/23 15:46:40  florian
 | |
|     * problem with with and classes fixed
 | |
| 
 | |
|   Revision 1.49  1998/09/23 12:03:55  peter
 | |
|     * overloading fix for array of const
 | |
| 
 | |
|   Revision 1.48  1998/09/22 15:37:23  peter
 | |
|     + array of const start
 | |
| 
 | |
|   Revision 1.47  1998/09/21 15:46:01  michael
 | |
|   Applied florians fix for check_rec_inittable
 | |
| 
 | |
|   Revision 1.46  1998/09/21 08:45:21  pierre
 | |
|     + added vmt_offset in tobjectdef.write for fututre use
 | |
|       (first steps to have objects without vmt if no virtual !!)
 | |
|     + added fpu_used field for tabstractprocdef  :
 | |
|       sets this level to 2 if the functions return with value in FPU
 | |
|       (is then set to correct value at parsing of implementation)
 | |
|       THIS MIGHT refuse some code with FPU expression too complex
 | |
|       that were accepted before and even in some cases
 | |
|       that don't overflow in fact
 | |
|       ( like if f : float; is a forward that finally in implementation
 | |
|        only uses one fpu register !!)
 | |
|       Nevertheless I think that it will improve security on
 | |
|       FPU operations !!
 | |
|     * most other changes only for UseBrowser code
 | |
|       (added symtable references for record and objects)
 | |
|       local switch for refs to args and local of each function
 | |
|       (static symtable still missing)
 | |
|       UseBrowser still not stable and probably broken by
 | |
|       the definition hash array !!
 | |
| 
 | |
|   Revision 1.45  1998/09/20 08:31:29  florian
 | |
|     + bit 6 of tpropinfo.propprocs is set, if the property contains a
 | |
|       constant index
 | |
| 
 | |
|   Revision 1.44  1998/09/19 15:23:58  florian
 | |
|     * rtti for ordtypes corrected
 | |
| 
 | |
|   Revision 1.43  1998/09/18 17:12:40  florian
 | |
|     * problem with writing of class references fixed
 | |
| 
 | |
|   Revision 1.42  1998/09/17 13:41:20  pierre
 | |
|   sizeof(TPOINT) problem
 | |
| 
 | |
|   Revision 1.40.2.2  1998/09/17 08:42:33  pierre
 | |
|   TPOINT sizeof fix
 | |
| 
 | |
|   Revision 1.41  1998/09/15 17:39:30  jonas
 | |
|     + bugfix from bugfix branch
 | |
| 
 | |
|   Revision 1.40.2.1  1998/09/15 17:35:32  jonas
 | |
|     * chenged string_typ in tstringdef.wideload from ansistring to widestring
 | |
| 
 | |
|   Revision 1.40  1998/09/09 15:34:00  peter
 | |
|     * removed warnings
 | |
| 
 | |
|   Revision 1.39  1998/09/08 10:23:44  pierre
 | |
|     * name field of filedef corrected
 | |
| 
 | |
|   Revision 1.38  1998/09/07 23:10:23  florian
 | |
|     * a lot of stuff fixed regarding rtti and publishing of properties,
 | |
|       basics should now work
 | |
| 
 | |
|   Revision 1.37  1998/09/07 19:33:24  florian
 | |
|     + some stuff for property rtti added:
 | |
|        - NameIndex of the TPropInfo record is now written correctly
 | |
|        - the DEFAULT/NODEFAULT keyword is supported now
 | |
|        - the default value and the storedsym/def are now written to
 | |
|          the PPU fiel
 | |
| 
 | |
|   Revision 1.36  1998/09/07 17:37:01  florian
 | |
|     * first fixes for published properties
 | |
| 
 | |
|   Revision 1.35  1998/09/06 22:42:02  florian
 | |
|     + rtti genreation for properties added
 | |
| 
 | |
|   Revision 1.34  1998/09/04 18:15:02  peter
 | |
|     * filedef updated
 | |
| 
 | |
|   Revision 1.33  1998/09/03 17:08:49  pierre
 | |
|     * better lines for stabs
 | |
|       (no scroll back to if before else part
 | |
|       no return to case line at jump outside case)
 | |
|     + source lines also if not in order
 | |
| 
 | |
|   Revision 1.32  1998/09/03 16:03:20  florian
 | |
|     + rtti generation
 | |
|     * init table generation changed
 | |
| 
 | |
|   Revision 1.31  1998/09/02 15:14:28  peter
 | |
|     * enum packing changed from len to max
 | |
| 
 | |
|   Revision 1.30  1998/09/01 17:37:29  peter
 | |
|     * removed debug writeln :(
 | |
| 
 | |
|   Revision 1.29  1998/09/01 12:53:25  peter
 | |
|     + aktpackenum
 | |
| 
 | |
|   Revision 1.28  1998/09/01 07:54:22  pierre
 | |
|     * UseBrowser a little updated (might still be buggy !!)
 | |
|     * bug in psub.pas in function specifier removed
 | |
|     * stdcall allowed in interface and in implementation
 | |
|       (FPC will not yet complain if it is missing in either part
 | |
|       because stdcall is only a dummy !!)
 | |
| 
 | |
|   Revision 1.27  1998/08/28 12:51:43  florian
 | |
|     + ansistring to pchar type cast fixed
 | |
| 
 | |
|   Revision 1.26  1998/08/25 12:42:44  pierre
 | |
|     * CDECL changed to CVAR for variables
 | |
|       specifications are read in structures also
 | |
|     + started adding GPC compatibility mode ( option  -Sp)
 | |
|     * names changed to lowercase
 | |
| 
 | |
|   Revision 1.25  1998/08/23 21:04:38  florian
 | |
|     + rtti generation for classes added
 | |
|     + new/dispose do now also a call to INITIALIZE/FINALIZE, if necessaray
 | |
| 
 | |
|   Revision 1.24  1998/08/20 12:53:26  peter
 | |
|     * object_options are always written for object syms
 | |
| 
 | |
|   Revision 1.23  1998/08/19 00:42:42  peter
 | |
|     + subrange types for enums
 | |
|     + checking for bounds type with ranges
 | |
| 
 | |
|   Revision 1.22  1998/08/17 10:10:10  peter
 | |
|     - removed OLDPPU
 | |
| 
 | |
|   Revision 1.21  1998/08/10 14:50:28  peter
 | |
|     + localswitches, moduleswitches, globalswitches splitting
 | |
| 
 | |
|   Revision 1.20  1998/07/18 22:54:30  florian
 | |
|     * some ansi/wide/longstring support fixed:
 | |
|        o parameter passing
 | |
|        o returning as result from functions
 | |
| 
 | |
|   Revision 1.19  1998/07/14 14:47:05  peter
 | |
|     * released NEWINPUT
 | |
| 
 | |
|   Revision 1.18  1998/07/10 10:51:04  peter
 | |
|     * m68k updates
 | |
| 
 | |
|   Revision 1.16  1998/07/07 11:20:13  peter
 | |
|     + NEWINPUT for a better inputfile and scanner object
 | |
| 
 | |
|   Revision 1.15  1998/06/24 14:48:37  peter
 | |
|     * ifdef newppu -> ifndef oldppu
 | |
| 
 | |
|   Revision 1.14  1998/06/16 08:56:31  peter
 | |
|     + targetcpu
 | |
|     * cleaner pmodules for newppu
 | |
| 
 | |
|   Revision 1.13  1998/06/15 15:38:09  pierre
 | |
|     * small bug in systems.pas corrected
 | |
|     + operators in different units better hanlded
 | |
| 
 | |
|   Revision 1.12  1998/06/15 14:30:12  daniel
 | |
| 
 | |
|   * Reverted my changes.
 | |
| 
 | |
|   Revision 1.10  1998/06/13 00:10:16  peter
 | |
|     * working browser and newppu
 | |
|     * some small fixes against crashes which occured in bp7 (but not in
 | |
|       fpc?!)
 | |
| 
 | |
|   Revision 1.9  1998/06/12 14:10:37  michael
 | |
|   * Fixed wrong code for ansistring
 | |
| 
 | |
|   Revision 1.8  1998/06/11 10:11:58  peter
 | |
|     * -gb works again
 | |
| 
 | |
|   Revision 1.7  1998/06/07 15:30:25  florian
 | |
|     + first working rtti
 | |
|     + data init/final. for local variables
 | |
| 
 | |
|   Revision 1.6  1998/06/05 14:37:37  pierre
 | |
|     * fixes for inline for operators
 | |
|     * inline procedure more correctly restricted
 | |
| 
 | |
|   Revision 1.5  1998/06/04 23:52:01  peter
 | |
|     * m68k compiles
 | |
|     + .def file creation moved to gendef.pas so it could also be used
 | |
|       for win32
 | |
| 
 | |
|   Revision 1.4  1998/06/04 09:55:45  pierre
 | |
|     * demangled name of procsym reworked to become independant of the mangling
 | |
|       scheme
 | |
| 
 | |
|   Revision 1.3  1998/06/03 22:49:03  peter
 | |
|     + wordbool,longbool
 | |
|     * rename bis,von -> high,low
 | |
|     * moved some systemunit loading/creating to psystem.pas
 | |
| 
 | |
|   Revision 1.2  1998/05/31 14:13:37  peter
 | |
|     * fixed call bugs with assembler readers
 | |
|     + OPR_SYMBOL to hold a symbol in the asm parser
 | |
|     * fixed staticsymtable vars which were acessed through %ebp instead of
 | |
|       name
 | |
| 
 | |
|   Revision 1.1  1998/05/27 19:45:09  peter
 | |
|     * symtable.pas splitted into includefiles
 | |
|     * symtable adapted for $ifndef OLDPPU
 | |
| 
 | |
| }
 | 
