|
@@ -0,0 +1,3873 @@
|
|
|
+{
|
|
|
+ $Id$
|
|
|
+ Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
|
|
|
+
|
|
|
+ This unit handles the symbol tables
|
|
|
+
|
|
|
+ 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.
|
|
|
+ ****************************************************************************
|
|
|
+}
|
|
|
+{$ifdef TP}
|
|
|
+ {$N+,E+,F+}
|
|
|
+{$endif}
|
|
|
+unit symtable;
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ {$define NONEXTFIELD}
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ interface
|
|
|
+
|
|
|
+ uses
|
|
|
+{$ifdef TP}
|
|
|
+ objects,
|
|
|
+{$endif}
|
|
|
+ strings,cobjects,
|
|
|
+ globtype,globals,tokens,systems,verbose,
|
|
|
+ aasm
|
|
|
+{$ifdef i386}
|
|
|
+ {$ifdef ag386bin}
|
|
|
+ ,i386base
|
|
|
+ {$else}
|
|
|
+ ,i386
|
|
|
+ {$endif}
|
|
|
+{$endif}
|
|
|
+{$ifdef m68k}
|
|
|
+ ,m68k
|
|
|
+{$endif}
|
|
|
+{$ifdef alpha}
|
|
|
+ ,alpha
|
|
|
+{$endif}
|
|
|
+{$ifdef GDB}
|
|
|
+ ,gdb
|
|
|
+{$endif}
|
|
|
+ ;
|
|
|
+
|
|
|
+{define NOLOCALBROWSER if you have problems with -bl option }
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ Some internal constants
|
|
|
+************************************************}
|
|
|
+
|
|
|
+ const
|
|
|
+ hasharraysize = 256;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ {$ifdef TP}
|
|
|
+ indexgrowsize = 256;
|
|
|
+ {$else}
|
|
|
+ indexgrowsize = 1024;
|
|
|
+ {$endif}
|
|
|
+{$else}
|
|
|
+ defhasharraysize = 16000;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ Constants
|
|
|
+************************************************}
|
|
|
+
|
|
|
+{$i symconst.inc}
|
|
|
+
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ Needed forward pointers
|
|
|
+************************************************}
|
|
|
+
|
|
|
+ type
|
|
|
+ { needed for owner (table) of symbol }
|
|
|
+ psymtable = ^tsymtable;
|
|
|
+ punitsymtable = ^tunitsymtable;
|
|
|
+
|
|
|
+ { needed for names by the definitions }
|
|
|
+ ptypesym = ^ttypesym;
|
|
|
+ penumsym = ^tenumsym;
|
|
|
+
|
|
|
+ pref = ^tref;
|
|
|
+ tref = object
|
|
|
+ nextref : pref;
|
|
|
+ posinfo : tfileposinfo;
|
|
|
+ moduleindex : word;
|
|
|
+ is_written : boolean;
|
|
|
+ constructor init(ref:pref;pos:pfileposinfo);
|
|
|
+ destructor done; virtual;
|
|
|
+ end;
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ TDef
|
|
|
+************************************************}
|
|
|
+
|
|
|
+{$i symdefh.inc}
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ TSym
|
|
|
+************************************************}
|
|
|
+
|
|
|
+{$i symsymh.inc}
|
|
|
+
|
|
|
+{************************************************
|
|
|
+ TSymtable
|
|
|
+************************************************}
|
|
|
+
|
|
|
+ tsymtabletype = (invalidsymtable,withsymtable,staticsymtable,
|
|
|
+ globalsymtable,unitsymtable,
|
|
|
+ objectsymtable,recordsymtable,
|
|
|
+ macrosymtable,localsymtable,
|
|
|
+ parasymtable,inlineparasymtable,
|
|
|
+ inlinelocalsymtable,stt_exceptsymtable,
|
|
|
+ { only used for PPU reading of static part
|
|
|
+ of a unit }
|
|
|
+ staticppusymtable);
|
|
|
+
|
|
|
+ tcallback = procedure(p : psym);
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ tnamedindexcallback = procedure(p : psym);
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ tsearchhasharray = array[0..hasharraysize-1] of psym;
|
|
|
+ psearchhasharray = ^tsearchhasharray;
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ tdefhasharray = array[0..defhasharraysize-1] of pdef;
|
|
|
+ pdefhasharray = ^tdefhasharray;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ tsymtable = object
|
|
|
+ symtabletype : tsymtabletype;
|
|
|
+ unitid : word; { each symtable gets a number }
|
|
|
+ name : pstring;
|
|
|
+ datasize : longint;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ symindex,
|
|
|
+ defindex : pindexarray;
|
|
|
+ symsearch : pdictionary;
|
|
|
+{$else}
|
|
|
+ searchroot : psym;
|
|
|
+ searchhasharray : psearchhasharray;
|
|
|
+ lastsym : psym;
|
|
|
+ rootdef : pdef;
|
|
|
+ defhasharraysize : longint;
|
|
|
+ defhasharray : pdefhasharray;
|
|
|
+{$endif}
|
|
|
+ next : psymtable;
|
|
|
+ defowner : pdef; { for records and objects }
|
|
|
+ { alignment used in this symtable }
|
|
|
+ alignment : longint;
|
|
|
+ { only used for parameter symtable to determine the offset relative }
|
|
|
+ { to the frame pointer and for local inline }
|
|
|
+ address_fixup : longint;
|
|
|
+ { this saves all definition to allow a proper clean up }
|
|
|
+ { separate lexlevel from symtable type }
|
|
|
+ symtablelevel : byte;
|
|
|
+ constructor init(t : tsymtabletype);
|
|
|
+ destructor done;virtual;
|
|
|
+ { access }
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ { indexes all defs from 0 to num and return num + 1 }
|
|
|
+ function number_defs:longint;
|
|
|
+ { indexes all symbols from 1 to num and return num }
|
|
|
+ function number_symbols:longint;
|
|
|
+{$endif}
|
|
|
+ function getdefnr(l : longint) : pdef;
|
|
|
+ function getsymnr(l : longint) : psym;
|
|
|
+ { load/write }
|
|
|
+ constructor load;
|
|
|
+ procedure write;
|
|
|
+ constructor loadas(typ : tsymtabletype);
|
|
|
+ procedure writeas;
|
|
|
+ procedure loaddefs;
|
|
|
+ procedure loadsyms;
|
|
|
+ procedure writedefs;
|
|
|
+ procedure writesyms;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ procedure deref;
|
|
|
+{$endif}
|
|
|
+ procedure clear;
|
|
|
+ function rename(const olds,news : stringid):psym;
|
|
|
+ procedure foreach(proc2call : tnamedindexcallback);
|
|
|
+ function insert(sym : psym):psym;
|
|
|
+ function search(const s : stringid) : psym;
|
|
|
+ function speedsearch(const s : stringid;speedvalue : longint) : psym;
|
|
|
+ procedure registerdef(p : pdef);
|
|
|
+ procedure allsymbolsused;
|
|
|
+ procedure allunitsused;
|
|
|
+ procedure check_forwards;
|
|
|
+ procedure checklabels;
|
|
|
+ { change alignment for args only parasymtable }
|
|
|
+ procedure set_alignment(_alignment : byte);
|
|
|
+ { find arg having offset only parasymtable }
|
|
|
+ function find_at_offset(l : longint) : pvarsym;
|
|
|
+{$ifdef CHAINPROCSYMS}
|
|
|
+ procedure chainprocsyms;
|
|
|
+{$endif CHAINPROCSYMS}
|
|
|
+ procedure load_browser;
|
|
|
+ procedure write_browser;
|
|
|
+{$ifdef BrowserLog}
|
|
|
+ procedure writebrowserlog;
|
|
|
+{$endif BrowserLog}
|
|
|
+{$ifdef GDB}
|
|
|
+ procedure concatstabto(asmlist : paasmoutput);virtual;
|
|
|
+{$endif GDB}
|
|
|
+ function getnewtypecount : word; virtual;
|
|
|
+ end;
|
|
|
+
|
|
|
+ tunitsymtable = object(tsymtable)
|
|
|
+ unittypecount : word;
|
|
|
+ unitsym : punitsym;
|
|
|
+{$ifdef GDB}
|
|
|
+ dbx_count : longint;
|
|
|
+ prev_dbx_counter : plongint;
|
|
|
+ dbx_count_ok : boolean;
|
|
|
+ is_stab_written : boolean;
|
|
|
+{$endif GDB}
|
|
|
+ constructor init(t : tsymtabletype;const n : string);
|
|
|
+ constructor loadasunit;
|
|
|
+ procedure writeasunit;
|
|
|
+{$ifdef GDB}
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ procedure orderdefs;
|
|
|
+{$endif}
|
|
|
+ procedure concattypestabto(asmlist : paasmoutput);
|
|
|
+{$endif GDB}
|
|
|
+ procedure load_symtable_refs;
|
|
|
+ function getnewtypecount : word; virtual;
|
|
|
+ end;
|
|
|
+
|
|
|
+ pwithsymtable = ^twithsymtable;
|
|
|
+ twithsymtable = object(tsymtable)
|
|
|
+{$ifndef NODIRECTWITH}
|
|
|
+ { used for withsymtable for allowing constructors }
|
|
|
+ direct_with : boolean;
|
|
|
+ { in fact it is a ptree }
|
|
|
+ withnode : pointer;
|
|
|
+ { ptree to load of direct with var }
|
|
|
+ { already usable before firstwith
|
|
|
+ needed for firstpass of function parameters PM }
|
|
|
+ withrefnode : pointer;
|
|
|
+{$endif def NODIRECTWITH}
|
|
|
+ constructor init;
|
|
|
+ destructor done;virtual;
|
|
|
+ end;
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Var / Consts
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ const
|
|
|
+ systemunit : punitsymtable = nil; { pointer to the system unit }
|
|
|
+ objpasunit : punitsymtable = nil; { pointer to the objpas unit }
|
|
|
+ current_object_option : symprop = sp_public;
|
|
|
+
|
|
|
+ var
|
|
|
+ { for STAB debugging }
|
|
|
+ globaltypecount : word;
|
|
|
+ pglobaltypecount : pword;
|
|
|
+
|
|
|
+ registerdef : boolean; { true, when defs should be registered }
|
|
|
+
|
|
|
+ defaultsymtablestack, { symtablestack after default units
|
|
|
+ have been loaded }
|
|
|
+ symtablestack : psymtable; { linked list of symtables }
|
|
|
+
|
|
|
+ srsym : psym; { result of the last search }
|
|
|
+ srsymtable : psymtable;
|
|
|
+ lastsrsym : psym; { last sym found in statement }
|
|
|
+ lastsrsymtable : psymtable;
|
|
|
+ lastsymknown : boolean;
|
|
|
+
|
|
|
+ forwardsallowed : boolean; { true, wenn forward pointers can be
|
|
|
+ inserted }
|
|
|
+
|
|
|
+ constsymtable : psymtable; { symtable were the constants can be
|
|
|
+ inserted }
|
|
|
+
|
|
|
+ voidpointerdef : ppointerdef; { pointer for Void-Pointerdef }
|
|
|
+ charpointerdef : ppointerdef; { pointer for Char-Pointerdef }
|
|
|
+ voidfarpointerdef : pfarpointerdef;
|
|
|
+
|
|
|
+ voiddef : porddef; { Pointer to Void (procedure) }
|
|
|
+ cchardef : porddef; { Pointer to Char }
|
|
|
+ u8bitdef : porddef; { Pointer to 8-Bit unsigned }
|
|
|
+ u16bitdef : porddef; { Pointer to 16-Bit unsigned }
|
|
|
+ u32bitdef : porddef; { Pointer to 32-Bit unsigned }
|
|
|
+ s32bitdef : porddef; { Pointer to 32-Bit signed }
|
|
|
+ booldef : porddef; { pointer to boolean type }
|
|
|
+ cformaldef : pformaldef; { unique formal definition }
|
|
|
+
|
|
|
+ cu64bitdef : porddef; { pointer to 64 bit unsigned def }
|
|
|
+ cs64bitintdef : porddef; { pointer to 64 bit signed def, }
|
|
|
+ { calculated by the int unit on i386 }
|
|
|
+
|
|
|
+ c64floatdef : pfloatdef; { pointer for realconstn }
|
|
|
+ s80floatdef : pfloatdef; { pointer to type of temp. floats }
|
|
|
+ s32fixeddef : pfloatdef; { pointer to type of temp. fixed }
|
|
|
+
|
|
|
+ cshortstringdef : pstringdef; { pointer to type of short string const }
|
|
|
+ clongstringdef : pstringdef; { pointer to type of long string const }
|
|
|
+ cansistringdef : pstringdef; { pointer to type of ansi string const }
|
|
|
+ cwidestringdef : pstringdef; { pointer to type of wide string const }
|
|
|
+ openshortstringdef : pstringdef; { pointer to type of an open shortstring,
|
|
|
+ needed for readln() }
|
|
|
+
|
|
|
+ cfiledef : pfiledef; { get the same definition for all file }
|
|
|
+ { uses for stabs }
|
|
|
+
|
|
|
+ firstglobaldef, { linked list of all globals defs }
|
|
|
+ lastglobaldef : pdef; { used to reset stabs/ranges }
|
|
|
+
|
|
|
+ class_tobject : pobjectdef; { pointer to the anchestor of all }
|
|
|
+ { clases }
|
|
|
+
|
|
|
+ aktprocsym : pprocsym; { pointer to the symbol for the
|
|
|
+ currently be parsed procedure }
|
|
|
+
|
|
|
+ aktcallprocsym : pprocsym; { pointer to the symbol for the
|
|
|
+ currently be called procedure,
|
|
|
+ only set/unset in firstcall }
|
|
|
+
|
|
|
+ aktvarsym : pvarsym; { pointer to the symbol for the
|
|
|
+ currently read var, only used
|
|
|
+ for variable directives }
|
|
|
+
|
|
|
+ procprefix : string; { eindeutige Namen bei geschachtel- }
|
|
|
+ { ten Unterprogrammen erzeugen }
|
|
|
+
|
|
|
+ lexlevel : longint; { level of code }
|
|
|
+ { 1 for main procedure }
|
|
|
+ { 2 for normal function or proc }
|
|
|
+ { higher for locals }
|
|
|
+ const
|
|
|
+ main_program_level = 1;
|
|
|
+ unit_init_level = 1;
|
|
|
+ normal_function_level = 2;
|
|
|
+ in_loading : boolean = false;
|
|
|
+
|
|
|
+ var
|
|
|
+
|
|
|
+ macros : psymtable; { pointer for die Symboltabelle mit }
|
|
|
+ { Makros }
|
|
|
+
|
|
|
+ read_member : boolean; { true, wenn Members aus einer PPU- }
|
|
|
+ { Datei gelesen werden, d.h. ein }
|
|
|
+ { varsym seine Adresse einlesen soll }
|
|
|
+
|
|
|
+ generrorsym : psym; { Jokersymbol, wenn das richtige }
|
|
|
+ { Symbol nicht gefunden wird }
|
|
|
+
|
|
|
+ generrordef : pdef; { Jokersymbol for eine fehlerhafte }
|
|
|
+ { Typdefinition }
|
|
|
+
|
|
|
+ aktobjectdef : pobjectdef; { used for private functions check !! }
|
|
|
+
|
|
|
+ const
|
|
|
+ { last operator which can be overloaded }
|
|
|
+ first_overloaded = PLUS;
|
|
|
+ last_overloaded = ASSIGNMENT;
|
|
|
+ var
|
|
|
+ overloaded_operators : array[first_overloaded..last_overloaded] of pprocsym;
|
|
|
+ { unequal is not equal}
|
|
|
+ const
|
|
|
+ overloaded_names : array [first_overloaded..last_overloaded] of string[16] =
|
|
|
+ ('plus','minus','star','slash','equal',
|
|
|
+ 'greater','lower','greater_or_equal',
|
|
|
+ 'lower_or_equal','as','is','in','sym_diff',
|
|
|
+ 'starstar','assign');
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Functions
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+{*** Misc ***}
|
|
|
+ function globaldef(const s : string) : pdef;
|
|
|
+
|
|
|
+{*** Search ***}
|
|
|
+ function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
|
|
|
+ procedure getsym(const s : stringid;notfounderror : boolean);
|
|
|
+ procedure getsymonlyin(p : psymtable;const s : stringid);
|
|
|
+
|
|
|
+{*** Forwards ***}
|
|
|
+ procedure save_forward(ppd : ppointerdef;typesym : ptypesym);
|
|
|
+ procedure resolve_forwards;
|
|
|
+
|
|
|
+{*** PPU Write/Loading ***}
|
|
|
+ procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
|
|
|
+ procedure closecurrentppu;
|
|
|
+ procedure numberunits;
|
|
|
+ procedure load_interface;
|
|
|
+
|
|
|
+{*** GDB ***}
|
|
|
+{$ifdef GDB}
|
|
|
+ function typeglobalnumber(const s : string) : string;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{*** Definition ***}
|
|
|
+ procedure reset_global_defs;
|
|
|
+
|
|
|
+{*** Object Helpers ***}
|
|
|
+ function search_class_member(pd : pobjectdef;const n : string) : psym;
|
|
|
+ function search_default_property(pd : pobjectdef) : ppropertysym;
|
|
|
+
|
|
|
+{*** Macro ***}
|
|
|
+ procedure def_macro(const s : string);
|
|
|
+ procedure set_macro(const s : string;value : string);
|
|
|
+
|
|
|
+{*** symtable stack ***}
|
|
|
+ procedure dellexlevel;
|
|
|
+{$ifdef DEBUG}
|
|
|
+ procedure test_symtablestack;
|
|
|
+ procedure list_symtablestack;
|
|
|
+{$endif DEBUG}
|
|
|
+
|
|
|
+{*** dispose of a pdefcoll (args of a function) ***}
|
|
|
+ procedure disposepdefcoll(var para1 : pdefcoll);
|
|
|
+
|
|
|
+{*** Init / Done ***}
|
|
|
+ procedure InitSymtable;
|
|
|
+ procedure DoneSymtable;
|
|
|
+
|
|
|
+
|
|
|
+implementation
|
|
|
+
|
|
|
+ uses
|
|
|
+ version,
|
|
|
+ types,ppu,
|
|
|
+ gendef,files
|
|
|
+ ,tree
|
|
|
+{$ifdef newcg}
|
|
|
+ ,cgbase
|
|
|
+{$else}
|
|
|
+ ,hcodegen
|
|
|
+{$endif}
|
|
|
+{$ifdef BrowserLog}
|
|
|
+ ,browlog
|
|
|
+{$endif BrowserLog}
|
|
|
+ ;
|
|
|
+
|
|
|
+ var
|
|
|
+ aktrecordsymtable : psymtable; { current record read from ppu symtable }
|
|
|
+ aktstaticsymtable : psymtable; { current static for local ppu symtable }
|
|
|
+{$ifdef GDB}
|
|
|
+ asmoutput : paasmoutput;
|
|
|
+{$endif GDB}
|
|
|
+{$ifdef TP}
|
|
|
+ {$ifndef dpmi}
|
|
|
+ symbolstream : temsstream; { stream which is used to store some info }
|
|
|
+ {$else}
|
|
|
+ symbolstream : tmemorystream;
|
|
|
+ {$endif}
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ {to dispose the global symtable of a unit }
|
|
|
+ const
|
|
|
+ dispose_global : boolean = false;
|
|
|
+ object_options : boolean = false;
|
|
|
+ memsizeinc = 2048; { for long stabstrings }
|
|
|
+ tagtypes : Set of tdeftype =
|
|
|
+ [recorddef,enumdef,
|
|
|
+ {$IfNDef GDBKnowsStrings}
|
|
|
+ stringdef,
|
|
|
+ {$EndIf not GDBKnowsStrings}
|
|
|
+ {$IfNDef GDBKnowsFiles}
|
|
|
+ filedef,
|
|
|
+ {$EndIf not GDBKnowsFiles}
|
|
|
+ objectdef];
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ Helper Routines
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ function demangledparas(s : string) : string;
|
|
|
+ var
|
|
|
+ r : string;
|
|
|
+ l : longint;
|
|
|
+ begin
|
|
|
+ demangledparas:='';
|
|
|
+ r:=',';
|
|
|
+ { delete leading $$'s }
|
|
|
+ l:=pos('$$',s);
|
|
|
+ while l<>0 do
|
|
|
+ begin
|
|
|
+ delete(s,1,l+1);
|
|
|
+ l:=pos('$$',s);
|
|
|
+ end;
|
|
|
+ l:=pos('$',s);
|
|
|
+ if l=0 then
|
|
|
+ exit;
|
|
|
+ delete(s,1,l);
|
|
|
+ l:=pos('$',s);
|
|
|
+ if l=0 then
|
|
|
+ l:=length(s)+1;
|
|
|
+ while s<>'' do
|
|
|
+ begin
|
|
|
+ r:=r+copy(s,1,l-1)+',';
|
|
|
+ delete(s,1,l);
|
|
|
+ end;
|
|
|
+ delete(r,1,1);
|
|
|
+ delete(r,length(r),1);
|
|
|
+ demangledparas:=r;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure numberunits;
|
|
|
+ var
|
|
|
+ counter : longint;
|
|
|
+ hp : pused_unit;
|
|
|
+ begin
|
|
|
+ counter:=1;
|
|
|
+ psymtable(current_module^.globalsymtable)^.unitid:=0;
|
|
|
+ hp:=pused_unit(current_module^.used_units.first);
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ psymtable(hp^.u^.globalsymtable)^.unitid:=counter;
|
|
|
+ inc(counter);
|
|
|
+ hp:=pused_unit(hp^.next);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure setstring(var p : pchar;const s : string);
|
|
|
+ begin
|
|
|
+{$ifdef TP}
|
|
|
+ if use_big then
|
|
|
+ begin
|
|
|
+ p:=pchar(symbolstream.getsize);
|
|
|
+ symbolstream.seek(longint(p));
|
|
|
+ symbolstream.writestr(@s);
|
|
|
+ end
|
|
|
+ else
|
|
|
+{$endif TP}
|
|
|
+ p:=strpnew(s);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ TRef
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ constructor tref.init(ref :pref;pos : pfileposinfo);
|
|
|
+ begin
|
|
|
+ nextref:=nil;
|
|
|
+ if pos<>nil then
|
|
|
+ posinfo:=pos^;
|
|
|
+ if assigned(current_module) then
|
|
|
+ moduleindex:=current_module^.unit_index;
|
|
|
+ if assigned(ref) then
|
|
|
+ ref^.nextref:=@self;
|
|
|
+ is_written:=false;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ destructor tref.done;
|
|
|
+ var
|
|
|
+ inputfile : pinputfile;
|
|
|
+ begin
|
|
|
+ inputfile:=get_source_file(moduleindex,posinfo.fileindex);
|
|
|
+ if inputfile<>nil then
|
|
|
+ dec(inputfile^.ref_count);
|
|
|
+ if assigned(nextref) then
|
|
|
+ dispose(nextref,done);
|
|
|
+ nextref:=nil;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ PPU Reading Writing
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+{$I symppu.inc}
|
|
|
+
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ Definition Helpers
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ function globaldef(const s : string) : pdef;
|
|
|
+
|
|
|
+ var st : string;
|
|
|
+ symt : psymtable;
|
|
|
+ begin
|
|
|
+ srsym := nil;
|
|
|
+ if pos('.',s) > 0 then
|
|
|
+ begin
|
|
|
+ st := copy(s,1,pos('.',s)-1);
|
|
|
+ getsym(st,false);
|
|
|
+ st := copy(s,pos('.',s)+1,255);
|
|
|
+ if assigned(srsym) then
|
|
|
+ begin
|
|
|
+ if srsym^.typ = unitsym then
|
|
|
+ begin
|
|
|
+ symt := punitsym(srsym)^.unitsymtable;
|
|
|
+ srsym := symt^.search(st);
|
|
|
+ end else srsym := nil;
|
|
|
+ end;
|
|
|
+ end else st := s;
|
|
|
+ if srsym = nil then getsym(st,false);
|
|
|
+ if srsym = nil then
|
|
|
+ getsymonlyin(systemunit,st);
|
|
|
+ if srsym^.typ<>typesym then
|
|
|
+ begin
|
|
|
+ Message(type_e_type_id_expected);
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ globaldef := ptypesym(srsym)^.definition;
|
|
|
+ end;
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ Symbol / Definition Resolving
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+const localsymtablestack : psymtable = nil;
|
|
|
+
|
|
|
+ function find_local_symtable(index : word) : psymtable;
|
|
|
+ var
|
|
|
+ p : psymtable;
|
|
|
+ begin
|
|
|
+ p:=localsymtablestack;
|
|
|
+ while assigned(p) do
|
|
|
+ begin
|
|
|
+ if p^.unitid=index then break
|
|
|
+ else
|
|
|
+ p:=p^.next;
|
|
|
+ end;
|
|
|
+ if (p=nil) then
|
|
|
+ comment(v_fatal,'Error in local browser');
|
|
|
+ find_local_symtable:=p;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure resolvesym(var d : psym);
|
|
|
+ begin
|
|
|
+ if longint(d)=$ffffffff then
|
|
|
+ d:=nil
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (longint(d) and $ffff)=$ffff then
|
|
|
+ d:=aktrecordsymtable^.getsymnr(longint(d) shr 16)
|
|
|
+ else
|
|
|
+ if (longint(d) and $ffff)=$fffe then
|
|
|
+ d:=aktstaticsymtable^.getsymnr(longint(d) shr 16)
|
|
|
+ else if (longint(d) and $ffff)>$8000 then
|
|
|
+ d:=find_local_symtable(longint(d) and $ffff)^.getsymnr(longint(d) shr 16)
|
|
|
+ else
|
|
|
+{$ifdef NEWMAP}
|
|
|
+ d:=psymtable(current_module^.map^[longint(d) and $ffff]^.globalsymtable)^.getsymnr(longint(d) shr 16);
|
|
|
+{$else NEWMAP}
|
|
|
+ d:=psymtable(current_module^.map^[longint(d) and $ffff])^.getsymnr(longint(d) shr 16);
|
|
|
+{$endif NEWMAP}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure resolvedef(var d : pdef);
|
|
|
+ begin
|
|
|
+ if longint(d)=$ffffffff then
|
|
|
+ d:=nil
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (longint(d) and $ffff)=$ffff then
|
|
|
+ d:=aktrecordsymtable^.getdefnr(longint(d) shr 16)
|
|
|
+ else
|
|
|
+ if (longint(d) and $ffff)=$fffe then
|
|
|
+ d:=aktstaticsymtable^.getdefnr(longint(d) shr 16)
|
|
|
+ else if (longint(d) and $ffff)>$8000 then
|
|
|
+ d:=find_local_symtable(longint(d) and $ffff)^.getdefnr(longint(d) shr 16)
|
|
|
+ else
|
|
|
+{$ifdef NEWMAP}
|
|
|
+ d:=psymtable(current_module^.map^[longint(d) and $ffff]^.globalsymtable)^.getdefnr(longint(d) shr 16);
|
|
|
+{$else NEWMAP}
|
|
|
+ d:=psymtable(current_module^.map^[longint(d) and $ffff])^.getdefnr(longint(d) shr 16);
|
|
|
+{$endif NEWMAP}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ Symbol Call Back Functions
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ procedure writesym(p : psym);
|
|
|
+ begin
|
|
|
+ p^.write;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ procedure derefsym(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ psym(p)^.deref;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure derefsymsdelayed(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if psym(p)^.typ in [absolutesym,propertysym] then
|
|
|
+ psym(p)^.deref;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure check_procsym_forward(sym : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if psym(sym)^.typ=procsym then
|
|
|
+ pprocsym(sym)^.check_forward
|
|
|
+ { check also object method table }
|
|
|
+ { we needn't to test the def list }
|
|
|
+ { because each object has to have a type sym }
|
|
|
+ else
|
|
|
+ if (psym(sym)^.typ=typesym) and
|
|
|
+ assigned(ptypesym(sym)^.definition) and
|
|
|
+ (ptypesym(sym)^.definition^.deftype=objectdef) then
|
|
|
+ pobjectdef(ptypesym(sym)^.definition)^.check_forwards;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure labeldefined(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if (psym(p)^.typ=labelsym) and
|
|
|
+ not(plabelsym(p)^.defined) then
|
|
|
+ Message1(sym_w_label_not_defined,p^.name);
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure unitsymbolused(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if (psym(p)^.typ=unitsym) and
|
|
|
+ (punitsym(p)^.refs=0) then
|
|
|
+ comment(V_info,'Unit '+p^.name+' is not used');
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure varsymbolused(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ var
|
|
|
+ oldaktfilepos : tfileposinfo;
|
|
|
+ begin
|
|
|
+ if (psym(p)^.typ=varsym) and
|
|
|
+ ((psym(p)^.owner^.symtabletype in [parasymtable,localsymtable,staticsymtable])) then
|
|
|
+ { unused symbol should be reported only if no }
|
|
|
+ { error is reported }
|
|
|
+ { if the symbol is in a register it is used }
|
|
|
+ { also don't count the value parameters which have local copies }
|
|
|
+ { also don't claim for high param of open parameters (PM) }
|
|
|
+ if (pvarsym(p)^.refs=0) and
|
|
|
+ (copy(p^.name,1,3)<>'val') and
|
|
|
+ (copy(p^.name,1,4)<>'high') and
|
|
|
+ (Errorcount=0) then
|
|
|
+ begin
|
|
|
+ oldaktfilepos:=aktfilepos;
|
|
|
+ aktfilepos:=psym(p)^.fileinfo;
|
|
|
+ if (psym(p)^.owner^.symtabletype=parasymtable) or pvarsym(p)^.islocalcopy then
|
|
|
+ Message1(sym_h_para_identifier_not_used,p^.name)
|
|
|
+ else
|
|
|
+ Message1(sym_n_local_identifier_not_used,p^.name);
|
|
|
+ aktfilepos:=oldaktfilepos;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+{$ifdef GDB}
|
|
|
+ procedure concatstab(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if psym(p)^.typ <> procsym then
|
|
|
+ psym(p)^.concatstabto(asmoutput);
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure concattypestab(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if psym(p)^.typ = typesym then
|
|
|
+ begin
|
|
|
+ psym(p)^.isstabwritten:=false;
|
|
|
+ psym(p)^.concatstabto(asmoutput);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure forcestabto(asmlist : paasmoutput; pd : pdef);
|
|
|
+ begin
|
|
|
+ if not pd^.is_def_stab_written then
|
|
|
+ begin
|
|
|
+ if assigned(pd^.sym) then
|
|
|
+ pd^.sym^.isusedinstab := true;
|
|
|
+ pd^.concatstabto(asmlist);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{$ifdef CHAINPROCSYMS}
|
|
|
+ procedure chainprocsym(p : psym);
|
|
|
+ var
|
|
|
+ storesymtablestack : psymtable;
|
|
|
+ begin
|
|
|
+ if p^.typ=procsym then
|
|
|
+ begin
|
|
|
+ storesymtablestack:=symtablestack;
|
|
|
+ symtablestack:=p^.owner^.next;
|
|
|
+ while assigned(symtablestack) do
|
|
|
+ begin
|
|
|
+ { search for same procsym in other units }
|
|
|
+ getsym(p^.name,false);
|
|
|
+ if assigned(srsym) and (srsym^.typ=procsym) then
|
|
|
+ begin
|
|
|
+ pprocsym(p)^.nextprocsym:=pprocsym(srsym);
|
|
|
+ symtablestack:=storesymtablestack;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else if srsym=nil then
|
|
|
+ symtablestack:=nil
|
|
|
+ else
|
|
|
+ symtablestack:=srsymtable^.next;
|
|
|
+ end;
|
|
|
+ symtablestack:=storesymtablestack;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ procedure write_refs(sym : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ psym(sym)^.write_references;
|
|
|
+ end;
|
|
|
+
|
|
|
+{$ifdef BrowserLog}
|
|
|
+ procedure add_to_browserlog(p : psym);
|
|
|
+ begin
|
|
|
+ p^.add_to_browserlog;
|
|
|
+ end;
|
|
|
+{$endif UseBrowser}
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Forward Resolving
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ type
|
|
|
+ presolvelist = ^tresolvelist;
|
|
|
+ tresolvelist = record
|
|
|
+ p : ppointerdef;
|
|
|
+ typ : ptypesym;
|
|
|
+ next : presolvelist;
|
|
|
+ end;
|
|
|
+
|
|
|
+ var
|
|
|
+ sroot : presolvelist;
|
|
|
+ procedure save_forward(ppd : ppointerdef;typesym : ptypesym);
|
|
|
+ var
|
|
|
+ p : presolvelist;
|
|
|
+ begin
|
|
|
+ new(p);
|
|
|
+ p^.next:=sroot;
|
|
|
+ p^.p:=ppd;
|
|
|
+ ppd^.defsym := typesym;
|
|
|
+ p^.typ:=typesym;
|
|
|
+ sroot:=p;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure resolve_forwards;
|
|
|
+ var
|
|
|
+ p : presolvelist;
|
|
|
+ begin
|
|
|
+ p:=sroot;
|
|
|
+ while p<>nil do
|
|
|
+ begin
|
|
|
+ sroot:=sroot^.next;
|
|
|
+ p^.p^.definition:=p^.typ^.definition;
|
|
|
+ dispose(p);
|
|
|
+ p:=sroot;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ Search Symtables for Syms
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ procedure getsym(const s : stringid;notfounderror : boolean);
|
|
|
+ var
|
|
|
+ speedvalue : longint;
|
|
|
+ begin
|
|
|
+ speedvalue:=getspeedvalue(s);
|
|
|
+ lastsrsym:=nil;
|
|
|
+ srsymtable:=symtablestack;
|
|
|
+ while assigned(srsymtable) do
|
|
|
+ begin
|
|
|
+ srsym:=srsymtable^.speedsearch(s,speedvalue);
|
|
|
+ if assigned(srsym) then
|
|
|
+ exit
|
|
|
+ else
|
|
|
+ srsymtable:=srsymtable^.next;
|
|
|
+ end;
|
|
|
+ if forwardsallowed then
|
|
|
+ begin
|
|
|
+ srsymtable:=symtablestack;
|
|
|
+ while (srsymtable^.symtabletype in [objectsymtable,recordsymtable]) do
|
|
|
+ srsymtable:=srsymtable^.next;
|
|
|
+ srsym:=new(ptypesym,init(s,nil));
|
|
|
+ srsym^.properties:=sp_forwarddef;
|
|
|
+ srsymtable^.insert(srsym);
|
|
|
+ end
|
|
|
+ else if notfounderror then
|
|
|
+ begin
|
|
|
+ Message1(sym_e_id_not_found,s);
|
|
|
+ srsym:=generrorsym;
|
|
|
+ end
|
|
|
+ else srsym:=nil;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure getsymonlyin(p : psymtable;const s : stringid);
|
|
|
+ begin
|
|
|
+ { the caller have to take care if srsym=nil (FK) }
|
|
|
+ srsym:=nil;
|
|
|
+ if assigned(p) then
|
|
|
+ begin
|
|
|
+ srsymtable:=p;
|
|
|
+ srsym:=srsymtable^.search(s);
|
|
|
+ if assigned(srsym) then
|
|
|
+ exit
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (punitsymtable(srsymtable)=punitsymtable(current_module^.globalsymtable)) then
|
|
|
+ begin
|
|
|
+ getsymonlyin(psymtable(current_module^.localsymtable),s);
|
|
|
+ if assigned(srsym) then
|
|
|
+ srsymtable:=psymtable(current_module^.localsymtable)
|
|
|
+ else
|
|
|
+ Message1(sym_e_id_not_found,s);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ Message1(sym_e_id_not_found,s);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
|
|
|
+ {Search for a symbol in a specified symbol table. Returns nil if
|
|
|
+ the symtable is not found, and also if the symbol cannot be found
|
|
|
+ in the desired symtable }
|
|
|
+ var hsymtab:Psymtable;
|
|
|
+ res:Psym;
|
|
|
+ begin
|
|
|
+ res:=nil;
|
|
|
+ hsymtab:=symtablestack;
|
|
|
+ while (hsymtab<>nil) and (hsymtab^.symtabletype<>symtabletype) do
|
|
|
+ hsymtab:=hsymtab^.next;
|
|
|
+ if hsymtab<>nil then
|
|
|
+ {We found the desired symtable. Now check if the symbol we
|
|
|
+ search for is defined in it }
|
|
|
+ res:=hsymtab^.search(symbol);
|
|
|
+ search_a_symtable:=res;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ TSYMTABLE
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ constructor tsymtable.init(t : tsymtabletype);
|
|
|
+ begin
|
|
|
+ symtabletype:=t;
|
|
|
+ symtablelevel:=0;
|
|
|
+ defowner:=nil;
|
|
|
+ unitid:=0;
|
|
|
+ next:=nil;
|
|
|
+ name:=nil;
|
|
|
+ address_fixup:=0;
|
|
|
+ datasize:=0;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ new(symindex,init(indexgrowsize));
|
|
|
+ new(defindex,init(indexgrowsize));
|
|
|
+ new(symsearch,init);
|
|
|
+ symsearch^.noclear:=true;
|
|
|
+{$else}
|
|
|
+ lastsym:=nil;
|
|
|
+ rootdef:=nil;
|
|
|
+ defhasharray:=nil;
|
|
|
+ defhasharraysize:=0;
|
|
|
+ searchroot:=nil;
|
|
|
+ searchhasharray:=nil;
|
|
|
+{$endif}
|
|
|
+ alignment:=def_alignment;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ destructor tsymtable.done;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ var
|
|
|
+ hp : pdef;
|
|
|
+ {$ifdef GDB}
|
|
|
+ last : pdef;
|
|
|
+ {$endif GDB}
|
|
|
+{$endif}
|
|
|
+ begin
|
|
|
+ stringdispose(name);
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ dispose(symindex,done);
|
|
|
+ dispose(defindex,done);
|
|
|
+ { symsearch can already be disposed or set to nil for withsymtable }
|
|
|
+ if assigned(symsearch) then
|
|
|
+ begin
|
|
|
+ dispose(symsearch,done);
|
|
|
+ symsearch:=nil;
|
|
|
+ end;
|
|
|
+{$else}
|
|
|
+ if assigned(defhasharray) then
|
|
|
+ begin
|
|
|
+ freemem(defhasharray,sizeof(pdef)*defhasharraysize);
|
|
|
+ defhasharray:=nil;
|
|
|
+ end;
|
|
|
+ { clear all entries, pprocsyms have still the definitions left }
|
|
|
+ clear;
|
|
|
+ {$ifdef GDB}
|
|
|
+ last := Nil;
|
|
|
+ {$endif GDB}
|
|
|
+ hp:=rootdef;
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ {$ifdef GDB}
|
|
|
+ if hp^.owner=@self then
|
|
|
+ begin
|
|
|
+ if assigned(last) then
|
|
|
+ last^.next := hp^.next;
|
|
|
+ {$endif GDB}
|
|
|
+ rootdef:=hp^.next;
|
|
|
+ dispose(hp,done);
|
|
|
+ {$ifdef GDB}
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ last := hp;
|
|
|
+ rootdef:=hp^.next;
|
|
|
+ end;
|
|
|
+ {$endif GDB}
|
|
|
+ hp:=rootdef;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ constructor twithsymtable.init;
|
|
|
+ begin
|
|
|
+ inherited init(withsymtable);
|
|
|
+{$ifndef NODIRECTWITH}
|
|
|
+ direct_with:=false;
|
|
|
+ withnode:=nil;
|
|
|
+ withrefnode:=nil;
|
|
|
+{$endif def NODIRECTWITH}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ destructor twithsymtable.done;
|
|
|
+ begin
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ symsearch:=nil;
|
|
|
+{$endif}
|
|
|
+ inherited done;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ Helpers
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+ function tsymtable.getnewtypecount : word;
|
|
|
+ begin
|
|
|
+ getnewtypecount:=pglobaltypecount^;
|
|
|
+ inc(pglobaltypecount^);
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure tsymtable.registerdef(p : pdef);
|
|
|
+ begin
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ defindex^.insert(p);
|
|
|
+{$else}
|
|
|
+ p^.next:=rootdef;
|
|
|
+ rootdef:=p;
|
|
|
+{$endif}
|
|
|
+ { set def owner and indexnb }
|
|
|
+ p^.owner:=@self;
|
|
|
+ end;
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+
|
|
|
+ procedure tsymtable.foreach(proc2call : tnamedindexcallback);
|
|
|
+ begin
|
|
|
+ symindex^.foreach(proc2call);
|
|
|
+ end;
|
|
|
+
|
|
|
+{$else}
|
|
|
+
|
|
|
+ procedure tsymtable.foreach(proc2call : tnamedindexcallback);
|
|
|
+
|
|
|
+ procedure a(p : psym);
|
|
|
+ { must be preorder, because it's used by reading in }
|
|
|
+ { a PPU file }
|
|
|
+ { what does this mean ? I need to index
|
|
|
+ so proc2call must be after left and before right !! PM }
|
|
|
+ begin
|
|
|
+ proc2call(p);
|
|
|
+ if assigned(p^.left) then
|
|
|
+ a(p^.left);
|
|
|
+ if assigned(p^.right) then
|
|
|
+ a(p^.right);
|
|
|
+ end;
|
|
|
+
|
|
|
+ var
|
|
|
+ i : longint;
|
|
|
+ begin
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ begin
|
|
|
+ for i:=0 to hasharraysize-1 do
|
|
|
+ if assigned(searchhasharray^[i]) then
|
|
|
+ a(searchhasharray^[i]);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if assigned(searchroot) then
|
|
|
+ a(searchroot);
|
|
|
+ end;
|
|
|
+
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+
|
|
|
+ function tsymtable.number_defs:longint;
|
|
|
+ var
|
|
|
+ pd : pdef;
|
|
|
+ counter : longint;
|
|
|
+ begin
|
|
|
+ counter:=0;
|
|
|
+ pd:=rootdef;
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ pd^.indexnb:=counter;
|
|
|
+ inc(counter);
|
|
|
+ pd:=pd^.next;
|
|
|
+ end;
|
|
|
+ number_defs:=counter;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ var symtable_index : longint;
|
|
|
+
|
|
|
+ procedure numbersym(p : psym);
|
|
|
+
|
|
|
+ begin
|
|
|
+ p^.indexnb:=symtable_index;
|
|
|
+ inc(symtable_index);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.number_symbols:longint;
|
|
|
+ var old_nr : longint;
|
|
|
+ begin
|
|
|
+ old_nr:=symtable_index;
|
|
|
+ symtable_index:=1;
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(numbersym);
|
|
|
+ {$else}
|
|
|
+ foreach(@numbersym);
|
|
|
+ {$endif}
|
|
|
+ number_symbols:=symtable_index-1;
|
|
|
+ symtable_index:=old_nr;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ LOAD / WRITE SYMTABLE FROM PPU
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+ procedure tsymtable.loaddefs;
|
|
|
+ var
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ counter : longint;
|
|
|
+ last : pdef;
|
|
|
+{$endif}
|
|
|
+ hp : pdef;
|
|
|
+ b : byte;
|
|
|
+ begin
|
|
|
+ { load start of definition section, which holds the amount of defs }
|
|
|
+ if current_ppu^.readentry<>ibstartdefs then
|
|
|
+ Message(unit_f_ppu_read_error);
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ if symtabletype=unitsymtable then
|
|
|
+ begin
|
|
|
+ defhasharraysize:=current_ppu^.getlongint;
|
|
|
+ getmem(defhasharray,sizeof(pdef)*defhasharraysize);
|
|
|
+ fillchar(defhasharray^,sizeof(pdef)*defhasharraysize,0);
|
|
|
+ end
|
|
|
+ else
|
|
|
+{$endif}
|
|
|
+ current_ppu^.getlongint;
|
|
|
+ { read definitions }
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ counter:=0;
|
|
|
+ rootdef:=nil;
|
|
|
+{$endif}
|
|
|
+ repeat
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ case b of
|
|
|
+ ibpointerdef : hp:=new(ppointerdef,load);
|
|
|
+ ibarraydef : hp:=new(parraydef,load);
|
|
|
+ iborddef : hp:=new(porddef,load);
|
|
|
+ ibfloatdef : hp:=new(pfloatdef,load);
|
|
|
+ ibprocdef : hp:=new(pprocdef,load);
|
|
|
+ ibstringdef : hp:=new(pstringdef,shortload);
|
|
|
+ iblongstringdef : hp:=new(pstringdef,longload);
|
|
|
+ ibansistringdef : hp:=new(pstringdef,ansiload);
|
|
|
+ ibwidestringdef : hp:=new(pstringdef,wideload);
|
|
|
+ ibrecorddef : hp:=new(precdef,load);
|
|
|
+ ibobjectdef : hp:=new(pobjectdef,load);
|
|
|
+ ibenumdef : hp:=new(penumdef,load);
|
|
|
+ ibsetdef : hp:=new(psetdef,load);
|
|
|
+ ibprocvardef : hp:=new(pprocvardef,load);
|
|
|
+ ibfiledef : hp:=new(pfiledef,load);
|
|
|
+ ibclassrefdef : hp:=new(pclassrefdef,load);
|
|
|
+ ibfarpointerdef : hp:=new(pfarpointerdef,load);
|
|
|
+ ibformaldef : hp:=new(pformaldef,load);
|
|
|
+ ibenddefs : break;
|
|
|
+ ibend : Message(unit_f_ppu_read_error);
|
|
|
+ else
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ end;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ hp^.owner:=@self;
|
|
|
+ defindex^.insert(hp);
|
|
|
+{$else}
|
|
|
+ { each def gets a number }
|
|
|
+ hp^.indexnb:=counter;
|
|
|
+ if counter=0 then
|
|
|
+ begin
|
|
|
+ rootdef:=hp;
|
|
|
+ last:=hp;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ last^.next:=hp;
|
|
|
+ last:=hp;
|
|
|
+ end;
|
|
|
+ if assigned(defhasharray) then
|
|
|
+ begin
|
|
|
+ if counter<defhasharraysize then
|
|
|
+ defhasharray^[counter]:=hp
|
|
|
+ else
|
|
|
+ internalerror(10997);
|
|
|
+ end;
|
|
|
+ inc(counter);
|
|
|
+{$endif}
|
|
|
+ until false;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ number_defs;
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.loadsyms;
|
|
|
+ var
|
|
|
+ b : byte;
|
|
|
+ sym : psym;
|
|
|
+ begin
|
|
|
+ { load start of definition section, which holds the amount of defs }
|
|
|
+ if current_ppu^.readentry<>ibstartsyms then
|
|
|
+ Message(unit_f_ppu_read_error);
|
|
|
+ { skip amount of symbols, not used currently }
|
|
|
+ current_ppu^.getlongint;
|
|
|
+ { load datasize of this symboltable }
|
|
|
+ datasize:=current_ppu^.getlongint;
|
|
|
+ { now read the symbols }
|
|
|
+ repeat
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ case b of
|
|
|
+ ibtypesym : sym:=new(ptypesym,load);
|
|
|
+ ibprocsym : sym:=new(pprocsym,load);
|
|
|
+ ibconstsym : sym:=new(pconstsym,load);
|
|
|
+ ibvarsym : sym:=new(pvarsym,load);
|
|
|
+ ibfuncretsym : sym:=new(pfuncretsym,load);
|
|
|
+ ibabsolutesym : sym:=new(pabsolutesym,load);
|
|
|
+ ibenumsym : sym:=new(penumsym,load);
|
|
|
+ ibtypedconstsym : sym:=new(ptypedconstsym,load);
|
|
|
+ ibpropertysym : sym:=new(ppropertysym,load);
|
|
|
+ ibunitsym : sym:=new(punitsym,load);
|
|
|
+ iblabelsym : sym:=new(plabelsym,load);
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ ibsyssym : sym:=new(psyssym,load);
|
|
|
+{$endif}
|
|
|
+ ibendsyms : break;
|
|
|
+ ibend : Message(unit_f_ppu_read_error);
|
|
|
+ else
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ end;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ sym^.owner:=@self;
|
|
|
+ symindex^.insert(sym);
|
|
|
+ symsearch^.insert(sym);
|
|
|
+{$else}
|
|
|
+ if not (symtabletype in [recordsymtable,objectsymtable]) then
|
|
|
+ begin
|
|
|
+ { don't deref absolute symbols there, because it's possible }
|
|
|
+ { that the var sym which the absolute sym refers, isn't }
|
|
|
+ { loaded }
|
|
|
+ { but syms must be derefered to determine the definition }
|
|
|
+ { because must know the varsym size when inserting the symbol }
|
|
|
+ if not(b in [ibabsolutesym,ibpropertysym]) then
|
|
|
+ sym^.deref;
|
|
|
+ end;
|
|
|
+ insert(sym);
|
|
|
+{$endif}
|
|
|
+ until false;
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ { symbol numbering for references }
|
|
|
+ number_symbols;
|
|
|
+
|
|
|
+ if not (symtabletype in [recordsymtable,objectsymtable]) then
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(derefsymsdelayed);
|
|
|
+ {$else}
|
|
|
+ foreach(@derefsymsdelayed);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.writedefs;
|
|
|
+ var
|
|
|
+ pd : pdef;
|
|
|
+ begin
|
|
|
+ { each definition get a number, write then the amount of defs to the
|
|
|
+ ibstartdef entry }
|
|
|
+{$ifdef Double_checksum}
|
|
|
+ current_ppu^.do_interface_crc:=false;
|
|
|
+{$endif Double_checksum}
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ current_ppu^.putlongint(defindex^.count);
|
|
|
+{$else}
|
|
|
+ current_ppu^.putlongint(number_defs);
|
|
|
+{$endif}
|
|
|
+ current_ppu^.writeentry(ibstartdefs);
|
|
|
+ { now write the definition }
|
|
|
+{$ifdef Double_checksum}
|
|
|
+ current_ppu^.do_interface_crc:=true;
|
|
|
+{$endif Double_checksum}
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ pd:=pdef(defindex^.first);
|
|
|
+{$else}
|
|
|
+ pd:=rootdef;
|
|
|
+{$endif}
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ pd^.write;
|
|
|
+ pd:=pdef(pd^.next);
|
|
|
+ end;
|
|
|
+ { write end of definitions }
|
|
|
+ current_ppu^.writeentry(ibenddefs);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.writesyms;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ var
|
|
|
+ pd : psym;
|
|
|
+{$endif}
|
|
|
+ begin
|
|
|
+ { each definition get a number, write then the amount of syms and the
|
|
|
+ datasize to the ibsymdef entry }
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ current_ppu^.putlongint(symindex^.count);
|
|
|
+{$else}
|
|
|
+ current_ppu^.putlongint(number_symbols);
|
|
|
+{$endif}
|
|
|
+ current_ppu^.putlongint(datasize);
|
|
|
+ current_ppu^.writeentry(ibstartsyms);
|
|
|
+ { foreach is used to write all symbols }
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ pd:=psym(symindex^.first);
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ pd^.write;
|
|
|
+ pd:=psym(pd^.next);
|
|
|
+ end;
|
|
|
+{$else}
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(writesym);
|
|
|
+ {$else}
|
|
|
+ foreach(@writesym);
|
|
|
+ {$endif}
|
|
|
+{$endif}
|
|
|
+ { end of symbols }
|
|
|
+ current_ppu^.writeentry(ibendsyms);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ procedure tsymtable.deref;
|
|
|
+ var
|
|
|
+ hp : pdef;
|
|
|
+ hs : psym;
|
|
|
+ begin
|
|
|
+ hp:=pdef(defindex^.first);
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ hp^.deref;
|
|
|
+ hp^.symderef;
|
|
|
+ hp:=pdef(hp^.next);
|
|
|
+ end;
|
|
|
+
|
|
|
+ hs:=psym(symindex^.first);
|
|
|
+ while assigned(hs) do
|
|
|
+ begin
|
|
|
+ hs^.deref;
|
|
|
+ hs:=psym(hs^.next);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+
|
|
|
+ constructor tsymtable.load;
|
|
|
+ var
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ hp : pdef;
|
|
|
+{$endif}
|
|
|
+ st_loading : boolean;
|
|
|
+ begin
|
|
|
+ st_loading:=in_loading;
|
|
|
+ in_loading:=true;
|
|
|
+{$ifndef NEWMAP}
|
|
|
+ current_module^.map^[0]:=@self;
|
|
|
+{$else NEWMAP}
|
|
|
+ current_module^.globalsymtable:=@self;
|
|
|
+{$endif NEWMAP}
|
|
|
+
|
|
|
+ symtabletype:=unitsymtable;
|
|
|
+ symtablelevel:=0;
|
|
|
+
|
|
|
+ { unused for units }
|
|
|
+ address_fixup:=0;
|
|
|
+
|
|
|
+ datasize:=0;
|
|
|
+ defowner:=nil;
|
|
|
+ name:=nil;
|
|
|
+ unitid:=0;
|
|
|
+ defowner:=nil;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ new(symindex,init(indexgrowsize));
|
|
|
+ new(defindex,init(indexgrowsize));
|
|
|
+ new(symsearch,init);
|
|
|
+ symsearch^.usehash;
|
|
|
+ symsearch^.noclear:=true;
|
|
|
+{$else}
|
|
|
+ lastsym:=nil;
|
|
|
+ next:=nil;
|
|
|
+ rootdef:=nil;
|
|
|
+ defhasharray:=nil;
|
|
|
+ defhasharraysize:=0;
|
|
|
+ { reset search arrays }
|
|
|
+ searchroot:=nil;
|
|
|
+ new(searchhasharray);
|
|
|
+ fillchar(searchhasharray^,sizeof(searchhasharray^),0);
|
|
|
+{$endif}
|
|
|
+ alignment:=def_alignment;
|
|
|
+
|
|
|
+ { load definitions }
|
|
|
+ loaddefs;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ { solve the references to other definitions for each definition }
|
|
|
+ {$ifdef STORENUMBER}
|
|
|
+ hp:=pdef(defindex^.first);
|
|
|
+ {$else}
|
|
|
+ hp:=rootdef;
|
|
|
+ {$endif}
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ hp^.deref;
|
|
|
+ { insert also the owner }
|
|
|
+ hp^.owner:=@self;
|
|
|
+ hp:=pdef(hp^.next);
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ { load symbols }
|
|
|
+ loadsyms;
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ deref;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{$ifdef NEWMAP}
|
|
|
+ { necessary for dependencies }
|
|
|
+ current_module^.globalsymtable:=nil;
|
|
|
+{$endif NEWMAP}
|
|
|
+ in_loading:=st_loading;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.write;
|
|
|
+ begin
|
|
|
+ { write definitions }
|
|
|
+ writedefs;
|
|
|
+ { write symbols }
|
|
|
+ writesyms;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ constructor tsymtable.loadas(typ : tsymtabletype);
|
|
|
+ var
|
|
|
+ storesymtable : psymtable;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ hp : pdef;
|
|
|
+{$endif}
|
|
|
+ st_loading : boolean;
|
|
|
+ begin
|
|
|
+ st_loading:=in_loading;
|
|
|
+ in_loading:=true;
|
|
|
+ symtabletype:=typ;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ new(symindex,init(indexgrowsize));
|
|
|
+ new(defindex,init(indexgrowsize));
|
|
|
+ new(symsearch,init);
|
|
|
+ symsearch^.noclear:=true;
|
|
|
+{$else}
|
|
|
+ lastsym:=nil;
|
|
|
+ next:=nil;
|
|
|
+ rootdef:=nil;
|
|
|
+ defhasharray:=nil;
|
|
|
+ defhasharraysize:=0;
|
|
|
+ searchroot:=nil;
|
|
|
+ searchhasharray:=nil;
|
|
|
+{$endif}
|
|
|
+ defowner:=nil;
|
|
|
+ storesymtable:=aktrecordsymtable;
|
|
|
+ if typ in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ aktrecordsymtable:=@self;
|
|
|
+ { used for local browser }
|
|
|
+ if typ=staticppusymtable then
|
|
|
+ begin
|
|
|
+ aktstaticsymtable:=@self;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ symsearch^.usehash;
|
|
|
+{$else}
|
|
|
+ new(searchhasharray);
|
|
|
+ fillchar(searchhasharray^,sizeof(searchhasharray^),0);
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+ name:=nil;
|
|
|
+ alignment:=def_alignment;
|
|
|
+ { isn't used there }
|
|
|
+ datasize:=0;
|
|
|
+ address_fixup:= 0;
|
|
|
+ { also unused }
|
|
|
+ unitid:=0;
|
|
|
+
|
|
|
+ { load definitions }
|
|
|
+ { we need the correct symtable for registering }
|
|
|
+ if not (typ in [recordsymtable,objectsymtable]) then
|
|
|
+ begin
|
|
|
+ next:=symtablestack;
|
|
|
+ symtablestack:=@self;
|
|
|
+ end;
|
|
|
+
|
|
|
+ loaddefs;
|
|
|
+
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ { solve the references of the symbols for each definition }
|
|
|
+ {$ifdef STORENUMBER}
|
|
|
+ hp:=pdef(defindex^.first);
|
|
|
+ {$else}
|
|
|
+ hp:=rootdef;
|
|
|
+ {$endif}
|
|
|
+ if not (typ in [recordsymtable,objectsymtable]) then
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ hp^.deref;
|
|
|
+ { insert also the owner }
|
|
|
+ hp^.owner:=@self;
|
|
|
+ hp:=pdef(hp^.next);
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ { load symbols }
|
|
|
+ loadsyms;
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ if not (typ in [recordsymtable,objectsymtable]) then
|
|
|
+ deref;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+ aktrecordsymtable:=storesymtable;
|
|
|
+ if not (typ in [recordsymtable,objectsymtable]) then
|
|
|
+ begin
|
|
|
+ symtablestack:=next;
|
|
|
+ end;
|
|
|
+ in_loading:=st_loading;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.writeas;
|
|
|
+ var
|
|
|
+ oldtyp : byte;
|
|
|
+ storesymtable : psymtable;
|
|
|
+ begin
|
|
|
+ oldtyp:=current_ppu^.entrytyp;
|
|
|
+ storesymtable:=aktrecordsymtable;
|
|
|
+ if symtabletype in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ aktrecordsymtable:=@self;
|
|
|
+ if (symtabletype in [recordsymtable,objectsymtable]) then
|
|
|
+ current_ppu^.entrytyp:=subentryid;
|
|
|
+ { write definitions }
|
|
|
+ writedefs;
|
|
|
+ { write symbols }
|
|
|
+ writesyms;
|
|
|
+ current_ppu^.entrytyp:=oldtyp;
|
|
|
+ aktrecordsymtable:=storesymtable;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ Get Symbol / Def by Number
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+
|
|
|
+ function tsymtable.getsymnr(l : longint) : psym;
|
|
|
+ var
|
|
|
+ hp : psym;
|
|
|
+ begin
|
|
|
+ hp:=psym(symindex^.search(l));
|
|
|
+ if hp=nil then
|
|
|
+ internalerror(10999);
|
|
|
+ getsymnr:=hp;
|
|
|
+ end;
|
|
|
+
|
|
|
+ function tsymtable.getdefnr(l : longint) : pdef;
|
|
|
+ var
|
|
|
+ hp : pdef;
|
|
|
+ begin
|
|
|
+ hp:=pdef(defindex^.search(l));
|
|
|
+ if hp=nil then
|
|
|
+ internalerror(10998);
|
|
|
+ getdefnr:=hp;
|
|
|
+ end;
|
|
|
+
|
|
|
+{$else}
|
|
|
+
|
|
|
+ function tsymtable.getsymnr(l : longint) : psym;
|
|
|
+ var
|
|
|
+ hp : psym;
|
|
|
+ i : longint;
|
|
|
+ begin
|
|
|
+ getsymnr:=nil;
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ begin
|
|
|
+ hp:=nil;
|
|
|
+ for i:=0 to hasharraysize-1 do
|
|
|
+ if assigned(searchhasharray^[i]) then
|
|
|
+ if (searchhasharray^[i]^.indexnb>l) then
|
|
|
+ break
|
|
|
+ else
|
|
|
+ hp:=searchhasharray^[i];
|
|
|
+ end
|
|
|
+ else
|
|
|
+ hp:=searchroot;
|
|
|
+ { hp has an index that is <= l }
|
|
|
+ { if hp's index = l we found }
|
|
|
+ { if hp^.right exists and is also <= l }
|
|
|
+ { the sym is in the right branch }
|
|
|
+ { else in the left }
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ if hp^.indexnb=l then
|
|
|
+ begin
|
|
|
+ getsymnr:=hp;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else if assigned(hp^.right) and (hp^.right^.indexnb<=l) then
|
|
|
+ hp:=hp^.right
|
|
|
+ else
|
|
|
+ hp:=hp^.left;
|
|
|
+ end;
|
|
|
+ InternalError(10999);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.getdefnr(l : longint) : pdef;
|
|
|
+ var
|
|
|
+ hp : pdef;
|
|
|
+ begin
|
|
|
+ if assigned(defhasharray) and
|
|
|
+ (l<defhasharraysize) and
|
|
|
+ assigned(defhasharray^[l]) and
|
|
|
+ (defhasharray^[l]^.indexnb=l) then
|
|
|
+ begin
|
|
|
+ getdefnr:=defhasharray^[l];
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ hp:=rootdef;
|
|
|
+ while (assigned(hp)) and (hp^.indexnb<>l) do
|
|
|
+ hp:=hp^.next;
|
|
|
+ if assigned(defhasharray) and
|
|
|
+ (l<defhasharraysize) then
|
|
|
+ if not assigned(defhasharray^[l]) then
|
|
|
+ defhasharray^[l]:=hp
|
|
|
+ else
|
|
|
+ begin
|
|
|
+{$ifdef debug}
|
|
|
+ if (l<defhasharraysize) and
|
|
|
+ (hp<>defhasharray^[l]) then
|
|
|
+ InternalError(10998);
|
|
|
+{$endif debug}
|
|
|
+ end;
|
|
|
+ if assigned(hp) then
|
|
|
+ getdefnr:=hp
|
|
|
+ else
|
|
|
+ InternalError(10998);
|
|
|
+ end;
|
|
|
+
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ Table Access
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+
|
|
|
+ procedure tsymtable.clear;
|
|
|
+ begin
|
|
|
+ { remove no entry from a withsymtable as it is only a pointer to the
|
|
|
+ recorddef or objectdef symtable }
|
|
|
+ if symtabletype=withsymtable then
|
|
|
+ exit;
|
|
|
+ symindex^.clear;
|
|
|
+ defindex^.clear;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.insert(sym:psym):psym;
|
|
|
+ var
|
|
|
+ hp : psymtable;
|
|
|
+ hsym : psym;
|
|
|
+ begin
|
|
|
+ { set owner and sym indexnb }
|
|
|
+ sym^.owner:=@self;
|
|
|
+{$ifdef CHAINPROCSYMS}
|
|
|
+ { set the nextprocsym field }
|
|
|
+ if sym^.typ=procsym then
|
|
|
+ chainprocsym(sym);
|
|
|
+{$endif CHAINPROCSYMS}
|
|
|
+ { writes the symbol in data segment if required }
|
|
|
+ { also sets the datasize of owner }
|
|
|
+ if not in_loading then
|
|
|
+ sym^.insert_in_data;
|
|
|
+ if (symtabletype in [staticsymtable,globalsymtable]) then
|
|
|
+ begin
|
|
|
+ hp:=symtablestack;
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ if hp^.symtabletype in [staticsymtable,globalsymtable] then
|
|
|
+ begin
|
|
|
+ hsym:=hp^.search(sym^.name);
|
|
|
+ if (assigned(hsym)) and
|
|
|
+ (hsym^.properties and sp_forwarddef=0) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+ hp:=hp^.next;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ { check for duplicate id in local and parsymtable symtable }
|
|
|
+ if (symtabletype=localsymtable) then
|
|
|
+ { to be on the sure side: }
|
|
|
+ begin
|
|
|
+ if assigned(next) and
|
|
|
+ (next^.symtabletype=parasymtable) then
|
|
|
+ begin
|
|
|
+ hsym:=next^.search(sym^.name);
|
|
|
+ if assigned(hsym) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end
|
|
|
+ else if (current_module^.flags and uf_local_browser)=0 then
|
|
|
+ internalerror(43789);
|
|
|
+ end;
|
|
|
+
|
|
|
+ { check for duplicate id in local symtable of methods }
|
|
|
+ if (symtabletype=localsymtable) and
|
|
|
+ assigned(next) and
|
|
|
+ assigned(next^.next) and
|
|
|
+ { funcretsym is allowed !! }
|
|
|
+ (sym^.typ <> funcretsym) and
|
|
|
+ (next^.next^.symtabletype=objectsymtable) then
|
|
|
+ begin
|
|
|
+ hsym:=search_class_member(pobjectdef(next^.next^.defowner),sym^.name);
|
|
|
+ { but private ids can be reused }
|
|
|
+ if assigned(hsym) and
|
|
|
+ ((hsym^.properties<>sp_private) or
|
|
|
+ (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+ { check for duplicate field id in inherited classes }
|
|
|
+ if (sym^.typ=varsym) and
|
|
|
+ (symtabletype=objectsymtable) and
|
|
|
+ assigned(defowner) then
|
|
|
+ begin
|
|
|
+ hsym:=search_class_member(pobjectdef(defowner),sym^.name);
|
|
|
+ { but private ids can be reused }
|
|
|
+ if assigned(hsym) and
|
|
|
+ ((hsym^.properties<>sp_private) or
|
|
|
+ (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+
|
|
|
+ if sym^.typ = typesym then
|
|
|
+ if assigned(ptypesym(sym)^.definition) then
|
|
|
+ begin
|
|
|
+ if not assigned(ptypesym(sym)^.definition^.owner) then
|
|
|
+ registerdef(ptypesym(sym)^.definition);
|
|
|
+{$ifdef GDB}
|
|
|
+ if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist)
|
|
|
+ and (symtabletype in [globalsymtable,staticsymtable]) then
|
|
|
+ begin
|
|
|
+ ptypesym(sym)^.isusedinstab := true;
|
|
|
+ sym^.concatstabto(debuglist);
|
|
|
+ end;
|
|
|
+{$endif GDB}
|
|
|
+ end;
|
|
|
+ { insert in index and search hash }
|
|
|
+ symindex^.insert(sym);
|
|
|
+ symsearch^.insert(sym);
|
|
|
+ insert:=sym;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.search(const s : stringid) : psym;
|
|
|
+ begin
|
|
|
+ search:=psym(symsearch^.search(s));
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.speedsearch(const s : stringid;speedvalue : longint) : psym;
|
|
|
+ var
|
|
|
+ hp : psym;
|
|
|
+ begin
|
|
|
+ hp:=psym(symsearch^.speedsearch(s,speedvalue));
|
|
|
+ if assigned(hp) then
|
|
|
+ begin
|
|
|
+ { reject non static members in static procedures,
|
|
|
+ be carefull aktprocsym^.definition is not allways
|
|
|
+ loaded already (PFV) }
|
|
|
+ if (symtabletype=objectsymtable) and
|
|
|
+ ((hp^.properties and sp_static)=0) and
|
|
|
+ allow_only_static
|
|
|
+ {assigned(aktprocsym) and
|
|
|
+ assigned(aktprocsym^.definition) and
|
|
|
+ ((aktprocsym^.definition^.options and postaticmethod)<>0)} then
|
|
|
+ Message(sym_e_only_static_in_static);
|
|
|
+ if (symtabletype=unitsymtable) and
|
|
|
+ assigned(punitsymtable(@self)^.unitsym) then
|
|
|
+ inc(punitsymtable(@self)^.unitsym^.refs);
|
|
|
+ { unitsym are only loaded for browsing PM }
|
|
|
+ { this was buggy anyway because we could use }
|
|
|
+ { unitsyms from other units in _USES !! }
|
|
|
+ if (symtabletype=unitsymtable) and (hp^.typ=unitsym) and
|
|
|
+ assigned(current_module) and (current_module^.globalsymtable<>@self) then
|
|
|
+ hp:=nil;
|
|
|
+ if assigned(hp) and
|
|
|
+ (cs_browser in aktmoduleswitches) and make_ref then
|
|
|
+ begin
|
|
|
+ hp^.lastref:=new(pref,init(hp^.lastref,@tokenpos));
|
|
|
+ { for symbols that are in tables without
|
|
|
+ browser info or syssyms (PM) }
|
|
|
+ if hp^.refcount=0 then
|
|
|
+ hp^.defref:=hp^.lastref;
|
|
|
+ inc(hp^.refcount);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ speedsearch:=hp;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.rename(const olds,news : stringid):psym;
|
|
|
+ begin
|
|
|
+ rename:=psym(symsearch^.rename(olds,news));
|
|
|
+ end;
|
|
|
+
|
|
|
+{$else}
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.clear;
|
|
|
+ var
|
|
|
+ w : longint;
|
|
|
+ begin
|
|
|
+ { remove no entry from a withsymtable as it is only a pointer to the
|
|
|
+ recorddef or objectdef symtable }
|
|
|
+ if symtabletype=withsymtable then
|
|
|
+ exit;
|
|
|
+ { remove all entry from a symbol table }
|
|
|
+ if assigned(searchroot) then
|
|
|
+ begin
|
|
|
+ dispose(searchroot,done);
|
|
|
+ searchroot:=nil;
|
|
|
+ end;
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ begin
|
|
|
+ for w:=0 to hasharraysize-1 do
|
|
|
+ if assigned(searchhasharray^[w]) then
|
|
|
+ begin
|
|
|
+ dispose(searchhasharray^[w],done);
|
|
|
+ searchhasharray^[w]:=nil;
|
|
|
+ end;
|
|
|
+ dispose(searchhasharray);
|
|
|
+ searchhasharray:=nil;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.insert(sym:psym):psym;
|
|
|
+ var
|
|
|
+ ref : pref;
|
|
|
+
|
|
|
+ function _insert(var osym : psym):psym;
|
|
|
+ {To prevent TP from allocating temp space for temp strings, we allocate
|
|
|
+ some temp strings manually. We can use two temp strings, plus a third
|
|
|
+ one that TP adds, where TP alone needs five temp strings!. Storing
|
|
|
+ these on the heap saves even more, totally 1016 bytes per recursion!}
|
|
|
+ var
|
|
|
+ s1,s2:^string;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ lasthfp,hfp : pforwardpointer;
|
|
|
+{$endif}
|
|
|
+ begin
|
|
|
+ if osym=nil then
|
|
|
+ begin
|
|
|
+ osym:=sym;
|
|
|
+ _insert:=osym;
|
|
|
+{$ifndef nonextfield}
|
|
|
+ if assigned(lastsym) then
|
|
|
+ lastsym^.nextsym:=sym;
|
|
|
+ lastsym:=sym;
|
|
|
+{$endif}
|
|
|
+ end
|
|
|
+
|
|
|
+ { first check speedvalue, to allow a fast insert }
|
|
|
+ else
|
|
|
+ if osym^.speedvalue>sym^.speedvalue then
|
|
|
+ _insert:=_insert(psym(osym^.right))
|
|
|
+ else
|
|
|
+ if osym^.speedvalue<sym^.speedvalue then
|
|
|
+ _insert:=_insert(psym(osym^.left))
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ new(s1);
|
|
|
+ new(s2);
|
|
|
+ s1^:=osym^.name;
|
|
|
+ s2^:=sym^.name;
|
|
|
+ if s1^>s2^ then
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+ _insert:=_insert(psym(osym^.right));
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if s1^<s2^ then
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+ _insert:=_insert(psym(osym^.left));
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ if (osym^.typ=typesym) and (osym^.properties=sp_forwarddef) then
|
|
|
+ begin
|
|
|
+ if (sym^.typ<>typesym) then
|
|
|
+ Message(sym_f_id_already_typed);
|
|
|
+ {
|
|
|
+ if (ptypesym(sym)^.definition^.deftype<>recorddef) and
|
|
|
+ (ptypesym(sym)^.definition^.deftype<>objectdef) then
|
|
|
+ Message(sym_f_type_must_be_rec_or_class);
|
|
|
+ }
|
|
|
+ ptypesym(osym)^.definition:=ptypesym(sym)^.definition;
|
|
|
+ osym^.properties:=sp_public;
|
|
|
+ { resolve the definition right now !! }
|
|
|
+ {forward types have two defref chained
|
|
|
+ the first corresponding to the location
|
|
|
+ of the
|
|
|
+ ptype = ^ttype;
|
|
|
+ and the second
|
|
|
+ to the line
|
|
|
+ ttype = record }
|
|
|
+ if cs_browser in aktmoduleswitches then
|
|
|
+ begin
|
|
|
+ new(ref,init(nil,@sym^.fileinfo));
|
|
|
+ ref^.nextref:=osym^.defref;
|
|
|
+ osym^.defref:=ref;
|
|
|
+ end;
|
|
|
+
|
|
|
+ { update all forwardpointers to this definition }
|
|
|
+ hfp:=ptypesym(osym)^.forwardpointer;
|
|
|
+ while assigned(hfp) do
|
|
|
+ begin
|
|
|
+ lasthfp:=hfp;
|
|
|
+ hfp^.def^.definition:=ptypesym(osym)^.definition;
|
|
|
+ hfp:=hfp^.next;
|
|
|
+ dispose(lasthfp);
|
|
|
+ end;
|
|
|
+
|
|
|
+ if ptypesym(osym)^.definition^.sym = ptypesym(sym) then
|
|
|
+ ptypesym(osym)^.definition^.sym := ptypesym(osym);
|
|
|
+{$ifdef GDB}
|
|
|
+ ptypesym(osym)^.isusedinstab := true;
|
|
|
+ if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) then
|
|
|
+ osym^.concatstabto(debuglist);
|
|
|
+{$endif GDB}
|
|
|
+ { don't do a done on sym
|
|
|
+ because it also disposes left and right !!
|
|
|
+ sym is new so it has no left nor right }
|
|
|
+ dispose(sym,done);
|
|
|
+ _insert:=osym;
|
|
|
+ end
|
|
|
+ else
|
|
|
+{$endif}
|
|
|
+ begin
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ _insert:=osym;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ var
|
|
|
+ hp : psymtable;
|
|
|
+ hsym : psym;
|
|
|
+ begin
|
|
|
+ { set owner and sym indexnb }
|
|
|
+ sym^.owner:=@self;
|
|
|
+{$ifdef CHAINPROCSYMS}
|
|
|
+ { set the nextprocsym field }
|
|
|
+ if sym^.typ=procsym then
|
|
|
+ chainprocsym(sym);
|
|
|
+{$endif CHAINPROCSYMS}
|
|
|
+ { writes the symbol in data segment if required }
|
|
|
+ { also sets the datasize of owner }
|
|
|
+ if not in_loading then
|
|
|
+ sym^.insert_in_data;
|
|
|
+ if (symtabletype in [staticsymtable,globalsymtable]) then
|
|
|
+ begin
|
|
|
+ hp:=symtablestack;
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ if hp^.symtabletype in [staticsymtable,globalsymtable] then
|
|
|
+ begin
|
|
|
+ hsym:=hp^.search(sym^.name);
|
|
|
+ if (assigned(hsym)) and
|
|
|
+ (hsym^.properties and sp_forwarddef=0) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+ hp:=hp^.next;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ { check for duplicate id in local and parsymtable symtable }
|
|
|
+ if (symtabletype=localsymtable) then
|
|
|
+ { to be on the sure side: }
|
|
|
+ begin
|
|
|
+ if assigned(next) and
|
|
|
+ (next^.symtabletype=parasymtable) then
|
|
|
+ begin
|
|
|
+ hsym:=next^.search(sym^.name);
|
|
|
+ if assigned(hsym) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end
|
|
|
+ else if (current_module^.flags and uf_local_browser)=0 then
|
|
|
+ internalerror(43789);
|
|
|
+ end;
|
|
|
+
|
|
|
+ { check for duplicate id in local symtable of methods }
|
|
|
+ if (symtabletype=localsymtable) and
|
|
|
+ assigned(next) and
|
|
|
+ assigned(next^.next) and
|
|
|
+ { funcretsym is allowed !! }
|
|
|
+ (sym^.typ <> funcretsym) and
|
|
|
+ (next^.next^.symtabletype=objectsymtable) then
|
|
|
+ begin
|
|
|
+ hsym:=search_class_member(pobjectdef(next^.next^.defowner),sym^.name);
|
|
|
+ { but private ids can be reused }
|
|
|
+ if assigned(hsym) and
|
|
|
+ ((hsym^.properties<>sp_private) or
|
|
|
+ (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+ { check for duplicate field id in inherited classes }
|
|
|
+ if (sym^.typ=varsym) and
|
|
|
+ (symtabletype=objectsymtable) and
|
|
|
+ assigned(defowner) then
|
|
|
+ begin
|
|
|
+ hsym:=search_class_member(pobjectdef(defowner),sym^.name);
|
|
|
+ { but private ids can be reused }
|
|
|
+ if assigned(hsym) and
|
|
|
+ ((hsym^.properties<>sp_private) or
|
|
|
+ (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
|
|
|
+ Message1(sym_e_duplicate_id,sym^.name);
|
|
|
+ end;
|
|
|
+
|
|
|
+ if sym^.typ = typesym then
|
|
|
+ if assigned(ptypesym(sym)^.definition) then
|
|
|
+ begin
|
|
|
+ if not assigned(ptypesym(sym)^.definition^.owner) then
|
|
|
+ registerdef(ptypesym(sym)^.definition);
|
|
|
+{$ifdef GDB}
|
|
|
+ if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist)
|
|
|
+ and (symtabletype in [globalsymtable,staticsymtable]) then
|
|
|
+ begin
|
|
|
+ ptypesym(sym)^.isusedinstab := true;
|
|
|
+ sym^.concatstabto(debuglist);
|
|
|
+ end;
|
|
|
+{$endif GDB}
|
|
|
+ end;
|
|
|
+ sym^.speedvalue:=getspeedvalue(sym^.name);
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ insert:=_insert(searchhasharray^[sym^.speedvalue mod hasharraysize])
|
|
|
+ else
|
|
|
+ insert:=_insert(searchroot);
|
|
|
+ { store the sym also in the index, must be after the insert the table
|
|
|
+ because }
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ symindex^.insert(sym);
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.search(const s : stringid) : psym;
|
|
|
+ begin
|
|
|
+ search:=speedsearch(s,getspeedvalue(s));
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.speedsearch(const s : stringid;speedvalue : longint) : psym;
|
|
|
+ var
|
|
|
+ hp : psym;
|
|
|
+ begin
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ hp:=searchhasharray^[speedvalue mod hasharraysize]
|
|
|
+ else
|
|
|
+ hp:=searchroot;
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ if speedvalue>hp^.speedvalue then
|
|
|
+ hp:=hp^.left
|
|
|
+ else
|
|
|
+ if speedvalue<hp^.speedvalue then
|
|
|
+ hp:=hp^.right
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (hp^.name=s) then
|
|
|
+{$else}
|
|
|
+ hp:=inherited speedsearch(s,speedvalue);
|
|
|
+ if assigned(hp) then
|
|
|
+{$endif}
|
|
|
+ begin
|
|
|
+ { reject non static members in static procedures,
|
|
|
+ be carefull aktprocsym^.definition is not allways
|
|
|
+ loaded already (PFV) }
|
|
|
+ if (symtabletype=objectsymtable) and
|
|
|
+ ((hp^.properties and sp_static)=0) and
|
|
|
+ allow_only_static
|
|
|
+ {assigned(aktprocsym) and
|
|
|
+ assigned(aktprocsym^.definition) and
|
|
|
+ ((aktprocsym^.definition^.options and postaticmethod)<>0)} then
|
|
|
+ Message(sym_e_only_static_in_static);
|
|
|
+ if (symtabletype=unitsymtable) and
|
|
|
+ assigned(punitsymtable(@self)^.unitsym) then
|
|
|
+ inc(punitsymtable(@self)^.unitsym^.refs);
|
|
|
+ { unitsym are only loaded for browsing PM }
|
|
|
+ { this was buggy anyway because we could use }
|
|
|
+ { unitsyms from other units in _USES !! }
|
|
|
+ if (symtabletype=unitsymtable) and (hp^.typ=unitsym) and
|
|
|
+ assigned(current_module) and (current_module^.globalsymtable<>@self) then
|
|
|
+ hp:=nil;
|
|
|
+ if assigned(hp) and
|
|
|
+ (cs_browser in aktmoduleswitches) and make_ref then
|
|
|
+ begin
|
|
|
+ hp^.lastref:=new(pref,init(hp^.lastref,@tokenpos));
|
|
|
+ { for symbols that are in tables without
|
|
|
+ browser info or syssyms (PM) }
|
|
|
+ if hp^.refcount=0 then
|
|
|
+ hp^.defref:=hp^.lastref;
|
|
|
+ inc(hp^.refcount);
|
|
|
+ end;
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ speedsearch:=hp;
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if s>hp^.name then
|
|
|
+ hp:=hp^.left
|
|
|
+ else
|
|
|
+ hp:=hp^.right;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ speedsearch:=nil;
|
|
|
+{$else}
|
|
|
+ end;
|
|
|
+ speedsearch:=hp;
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tsymtable.rename(const olds,news : stringid):psym;
|
|
|
+ var
|
|
|
+ spdval : longint;
|
|
|
+ lasthp,
|
|
|
+ hp,hp2,hp3 : psym;
|
|
|
+
|
|
|
+ function _insert(var osym:psym):psym;
|
|
|
+ var
|
|
|
+ s1,s2:^string;
|
|
|
+ begin
|
|
|
+ if osym=nil then
|
|
|
+ begin
|
|
|
+ osym:=hp;
|
|
|
+ _insert:=osym;
|
|
|
+ end
|
|
|
+ { first check speedvalue, to allow a fast insert }
|
|
|
+ else
|
|
|
+ if osym^.speedvalue>hp^.speedvalue then
|
|
|
+ _insert:=_insert(osym^.right)
|
|
|
+ else
|
|
|
+ if osym^.speedvalue<hp^.speedvalue then
|
|
|
+ _insert:=_insert(osym^.left)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ new(s1);
|
|
|
+ new(s2);
|
|
|
+ s1^:=osym^._name^;
|
|
|
+ s2^:=hp^._name^;
|
|
|
+ if s1^>s2^ then
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+ _insert:=_insert(osym^.right);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if s1^<s2^ then
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+ _insert:=_insert(osym^.left);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ dispose(s2);
|
|
|
+ dispose(s1);
|
|
|
+ _insert:=osym;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure inserttree(p:psym);
|
|
|
+ begin
|
|
|
+ if assigned(p) then
|
|
|
+ begin
|
|
|
+ inserttree(p^.left);
|
|
|
+ inserttree(p^.right);
|
|
|
+ _insert(p);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ begin
|
|
|
+ spdval:=getspeedvalue(olds);
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ hp:=searchhasharray^[spdval mod hasharraysize]
|
|
|
+ else
|
|
|
+ hp:=searchroot;
|
|
|
+ lasthp:=nil;
|
|
|
+ while assigned(hp) do
|
|
|
+ begin
|
|
|
+ if spdval>hp^.speedvalue then
|
|
|
+ begin
|
|
|
+ lasthp:=hp;
|
|
|
+ hp:=hp^.left
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if spdval<hp^.speedvalue then
|
|
|
+ begin
|
|
|
+ lasthp:=hp;
|
|
|
+ hp:=hp^.right
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (hp^.name=olds) then
|
|
|
+ begin
|
|
|
+ { get in hp2 the replacer for the root or hasharr }
|
|
|
+ hp2:=hp^.left;
|
|
|
+ hp3:=hp^.right;
|
|
|
+ if not assigned(hp2) then
|
|
|
+ begin
|
|
|
+ hp2:=hp^.right;
|
|
|
+ hp3:=hp^.left;
|
|
|
+ end;
|
|
|
+ { remove entry from the tree }
|
|
|
+ if assigned(lasthp) then
|
|
|
+ begin
|
|
|
+ if lasthp^.left=hp then
|
|
|
+ lasthp^.left:=hp2
|
|
|
+ else
|
|
|
+ lasthp^.right:=hp2;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ searchhasharray^[spdval mod hasharraysize]:=hp2
|
|
|
+ else
|
|
|
+ searchroot:=hp2;
|
|
|
+ end;
|
|
|
+ { reinsert the hp3 }
|
|
|
+ inserttree(hp3);
|
|
|
+ { reinsert }
|
|
|
+ hp^.setname(news);
|
|
|
+ hp^.speedvalue:=getspeedvalue(news);
|
|
|
+ if assigned(searchhasharray) then
|
|
|
+ rename:=_insert(searchhasharray^[hp^.speedvalue mod hasharraysize])
|
|
|
+ else
|
|
|
+ rename:=_insert(searchroot);
|
|
|
+ exit;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if olds>hp^.name then
|
|
|
+ begin
|
|
|
+ lasthp:=hp;
|
|
|
+ hp:=hp^.left
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ lasthp:=hp;
|
|
|
+ hp:=hp^.right;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+{$endif}
|
|
|
+
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ Browser
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+ procedure tsymtable.load_browser;
|
|
|
+ var
|
|
|
+ b : byte;
|
|
|
+ sym : psym;
|
|
|
+ prdef : pdef;
|
|
|
+ oldrecsyms : psymtable;
|
|
|
+ begin
|
|
|
+ if symtabletype in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ begin
|
|
|
+ oldrecsyms:=aktrecordsymtable;
|
|
|
+ aktrecordsymtable:=@self;
|
|
|
+ end;
|
|
|
+ if symtabletype=staticppusymtable then
|
|
|
+ aktstaticsymtable:=@self;
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ if b <> ibbeginsymtablebrowser then
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ repeat
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ case b of
|
|
|
+ ibsymref : begin
|
|
|
+ sym:=readsymref;
|
|
|
+ resolvesym(sym);
|
|
|
+ if assigned(sym) then
|
|
|
+ sym^.load_references;
|
|
|
+ end;
|
|
|
+ ibdefref : begin
|
|
|
+ prdef:=readdefref;
|
|
|
+ resolvedef(prdef);
|
|
|
+ if assigned(prdef) then
|
|
|
+ begin
|
|
|
+ if prdef^.deftype<>procdef then
|
|
|
+ Message(unit_f_ppu_read_error);
|
|
|
+ pprocdef(prdef)^.load_references;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ ibendsymtablebrowser : break;
|
|
|
+ else
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ end;
|
|
|
+ until false;
|
|
|
+ if symtabletype in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ aktrecordsymtable:=oldrecsyms;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tsymtable.write_browser;
|
|
|
+ var
|
|
|
+ oldrecsyms : psymtable;
|
|
|
+ begin
|
|
|
+ { symbol numbering for references
|
|
|
+ should have been done in write PM
|
|
|
+ number_symbols;
|
|
|
+ number_defs; }
|
|
|
+
|
|
|
+ if symtabletype in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ begin
|
|
|
+ oldrecsyms:=aktrecordsymtable;
|
|
|
+ aktrecordsymtable:=@self;
|
|
|
+ end;
|
|
|
+ current_ppu^.writeentry(ibbeginsymtablebrowser);
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(write_refs);
|
|
|
+ {$else}
|
|
|
+ foreach(@write_refs);
|
|
|
+ {$endif}
|
|
|
+ current_ppu^.writeentry(ibendsymtablebrowser);
|
|
|
+ if symtabletype in [recordsymtable,objectsymtable,
|
|
|
+ parasymtable,localsymtable] then
|
|
|
+ aktrecordsymtable:=oldrecsyms;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{$ifdef BrowserLog}
|
|
|
+ procedure tsymtable.writebrowserlog;
|
|
|
+ begin
|
|
|
+ if cs_browser in aktmoduleswitches then
|
|
|
+ begin
|
|
|
+ if assigned(name) then
|
|
|
+ Browserlog.AddLog('---Symtable '+name^)
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if (symtabletype=recordsymtable) and
|
|
|
+ assigned(defowner^.sym) then
|
|
|
+ Browserlog.AddLog('---Symtable '+defowner^.sym^.name)
|
|
|
+ else
|
|
|
+ Browserlog.AddLog('---Symtable with no name');
|
|
|
+ end;
|
|
|
+ Browserlog.Ident;
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(add_to_browserlog);
|
|
|
+ {$else}
|
|
|
+ foreach(@add_to_browserlog);
|
|
|
+ {$endif}
|
|
|
+ browserlog.Unident;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+{$endif BrowserLog}
|
|
|
+
|
|
|
+
|
|
|
+{***********************************************
|
|
|
+ Process all entries
|
|
|
+***********************************************}
|
|
|
+
|
|
|
+ { checks, if all procsyms and methods are defined }
|
|
|
+ procedure tsymtable.check_forwards;
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(check_procsym_forward);
|
|
|
+ {$else}
|
|
|
+ foreach(@check_procsym_forward);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure tsymtable.checklabels;
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(labeldefined);
|
|
|
+ {$else}
|
|
|
+ foreach(@labeldefined);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure tsymtable.set_alignment(_alignment : byte);
|
|
|
+ var
|
|
|
+ sym : pvarsym;
|
|
|
+ l : longint;
|
|
|
+ begin
|
|
|
+ { this can not be done if there is an
|
|
|
+ hasharray ! }
|
|
|
+ alignment:=_alignment;
|
|
|
+ if (symtabletype<>parasymtable)
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ or assigned(searchhasharray)
|
|
|
+{$endif}
|
|
|
+ then
|
|
|
+ internalerror(1111);
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ sym:=pvarsym(symindex^.first);
|
|
|
+{$else STORENUMBER}
|
|
|
+ sym:=pvarsym(searchroot);
|
|
|
+{$endif STORENUMBER}
|
|
|
+ datasize:=0;
|
|
|
+ { there can be only varsyms }
|
|
|
+ while assigned(sym) do
|
|
|
+ begin
|
|
|
+ l:=sym^.getpushsize;
|
|
|
+ sym^.address:=datasize;
|
|
|
+ datasize:=align(datasize+l,alignment);
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ sym:=pvarsym(sym^.next);
|
|
|
+{$else STORENUMBER}
|
|
|
+ sym:=pvarsym(sym^.nextsym);
|
|
|
+{$endif STORENUMBER}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ function tsymtable.find_at_offset(l : longint) : pvarsym;
|
|
|
+ var
|
|
|
+ sym : pvarsym;
|
|
|
+ begin
|
|
|
+ find_at_offset:=nil;
|
|
|
+ { this can not be done if there is an
|
|
|
+ hasharray ! }
|
|
|
+ if (symtabletype<>parasymtable)
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ or assigned(searchhasharray)
|
|
|
+{$endif}
|
|
|
+ then
|
|
|
+ internalerror(1111);
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ sym:=pvarsym(symindex^.first);
|
|
|
+{$else STORENUMBER}
|
|
|
+ sym:=pvarsym(searchroot);
|
|
|
+{$endif STORENUMBER}
|
|
|
+ while assigned(sym) do
|
|
|
+ begin
|
|
|
+ if sym^.address+address_fixup=l then
|
|
|
+ begin
|
|
|
+ find_at_offset:=sym;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ sym:=pvarsym(sym^.next);
|
|
|
+{$else STORENUMBER}
|
|
|
+ sym:=pvarsym(sym^.nextsym);
|
|
|
+{$endif STORENUMBER}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure tsymtable.allunitsused;
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(unitsymbolused);
|
|
|
+ {$else}
|
|
|
+ foreach(@unitsymbolused);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure tsymtable.allsymbolsused;
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(varsymbolused);
|
|
|
+ {$else}
|
|
|
+ foreach(@varsymbolused);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+{$ifdef CHAINPROCSYMS}
|
|
|
+ procedure tsymtable.chainprocsyms;
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(chainprocsym);
|
|
|
+ {$else}
|
|
|
+ foreach(@chainprocsym);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+{$endif CHAINPROCSYMS}
|
|
|
+
|
|
|
+{$ifdef GDB}
|
|
|
+ procedure tsymtable.concatstabto(asmlist : paasmoutput);
|
|
|
+ begin
|
|
|
+ asmoutput:=asmlist;
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(concatstab);
|
|
|
+ {$else}
|
|
|
+ foreach(@concatstab);
|
|
|
+ {$endif}
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ TUNITSYMTABLE
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ constructor tunitsymtable.init(t : tsymtabletype; const n : string);
|
|
|
+ begin
|
|
|
+ inherited init(t);
|
|
|
+ name:=stringdup(upper(n));
|
|
|
+ unitid:=0;
|
|
|
+ unitsym:=nil;
|
|
|
+{$ifdef STORENUMBER}
|
|
|
+ symsearch^.usehash;
|
|
|
+{$else}
|
|
|
+ { create a hasharray }
|
|
|
+ new(searchhasharray);
|
|
|
+ fillchar(searchhasharray^,sizeof(searchhasharray^),0);
|
|
|
+{$endif}
|
|
|
+ { reset GDB things }
|
|
|
+{$ifdef GDB}
|
|
|
+ if t = globalsymtable then
|
|
|
+ begin
|
|
|
+ prev_dbx_counter := dbx_counter;
|
|
|
+ dbx_counter := @dbx_count;
|
|
|
+ end;
|
|
|
+ is_stab_written:=false;
|
|
|
+ if cs_gdb_dbx in aktglobalswitches then
|
|
|
+ begin
|
|
|
+ dbx_count := 0;
|
|
|
+ if (symtabletype=globalsymtable) then
|
|
|
+ pglobaltypecount := @unittypecount;
|
|
|
+ debuglist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0'))));
|
|
|
+ unitid:=current_module^.unitcount;
|
|
|
+ inc(current_module^.unitcount);
|
|
|
+ debuglist^.concat(new(pai_asm_comment,init(strpnew('Global '+name^+' has index '+tostr(unitid)))));
|
|
|
+ end;
|
|
|
+{$endif GDB}
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ constructor tunitsymtable.loadasunit;
|
|
|
+ var
|
|
|
+ storeGlobalTypeCount : pword;
|
|
|
+ b : byte;
|
|
|
+ begin
|
|
|
+ unitsym:=nil;
|
|
|
+ unitid:=0;
|
|
|
+ if (current_module^.flags and uf_has_dbx)<>0 then
|
|
|
+ begin
|
|
|
+ storeGlobalTypeCount:=PGlobalTypeCount;
|
|
|
+ PglobalTypeCount:=@UnitTypeCount;
|
|
|
+ end;
|
|
|
+
|
|
|
+ { load symtables }
|
|
|
+ inherited load;
|
|
|
+ { set the name after because it is set to nil in tsymtable.load !! }
|
|
|
+ name:=stringdup(current_module^.modulename^);
|
|
|
+
|
|
|
+ { dbx count }
|
|
|
+{$ifdef GDB}
|
|
|
+ if (current_module^.flags and uf_has_dbx)<>0 then
|
|
|
+ begin
|
|
|
+ b := current_ppu^.readentry;
|
|
|
+ if b <> ibdbxcount then
|
|
|
+ Message(unit_f_ppu_dbx_count_problem)
|
|
|
+ else
|
|
|
+ dbx_count := readlong;
|
|
|
+ dbx_count_ok := true;
|
|
|
+ PGlobalTypeCount:=storeGlobalTypeCount;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ dbx_count := 0;
|
|
|
+ is_stab_written:=false;
|
|
|
+{$endif GDB}
|
|
|
+
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ if b<>ibendimplementation then
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tunitsymtable.load_symtable_refs;
|
|
|
+ var
|
|
|
+ b : byte;
|
|
|
+ unitindex : word;
|
|
|
+ begin
|
|
|
+{$ifndef STORENUMBER}
|
|
|
+ number_defs;
|
|
|
+ number_symbols;
|
|
|
+{$endif}
|
|
|
+ if ((current_module^.flags and uf_local_browser)<>0) then
|
|
|
+ begin
|
|
|
+ current_module^.localsymtable:=new(psymtable,loadas(staticppusymtable));
|
|
|
+ psymtable(current_module^.localsymtable)^.name:=
|
|
|
+ stringdup('implementation of '+psymtable(current_module^.globalsymtable)^.name^);
|
|
|
+ end;
|
|
|
+ { load browser }
|
|
|
+ if (current_module^.flags and uf_has_browser)<>0 then
|
|
|
+ begin
|
|
|
+ {if not (cs_browser in aktmoduleswitches) then
|
|
|
+ current_ppu^.skipuntilentry(ibendbrowser)
|
|
|
+ else }
|
|
|
+ begin
|
|
|
+ load_browser;
|
|
|
+ unitindex:=1;
|
|
|
+ while assigned(current_module^.map^[unitindex]) do
|
|
|
+ begin
|
|
|
+ {each unit wrote one browser entry }
|
|
|
+ load_browser;
|
|
|
+ inc(unitindex);
|
|
|
+ end;
|
|
|
+ b:=current_ppu^.readentry;
|
|
|
+ if b<>ibendbrowser then
|
|
|
+ Message1(unit_f_ppu_invalid_entry,tostr(b));
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ if ((current_module^.flags and uf_local_browser)<>0) then
|
|
|
+ psymtable(current_module^.localsymtable)^.load_browser;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tunitsymtable.writeasunit;
|
|
|
+ var
|
|
|
+ pu : pused_unit;
|
|
|
+ begin
|
|
|
+ { first the unitname }
|
|
|
+ current_ppu^.putstring(name^);
|
|
|
+ current_ppu^.writeentry(ibmodulename);
|
|
|
+
|
|
|
+ writesourcefiles;
|
|
|
+
|
|
|
+ writeusedunit;
|
|
|
+
|
|
|
+ { write the objectfiles and libraries that come for this unit,
|
|
|
+ preserve the containers becuase they are still needed to load
|
|
|
+ the link.res. All doesn't depend on the crc! It doesn't matter
|
|
|
+ if a unit is in a .o or .a file }
|
|
|
+ current_ppu^.do_crc:=false;
|
|
|
+ writecontainer(current_module^.linkunitfiles,iblinkunitfiles,true,true);
|
|
|
+ writecontainer(current_module^.linkofiles,iblinkofiles,true,false);
|
|
|
+ writecontainer(current_module^.linksharedlibs,iblinksharedlibs,true,true);
|
|
|
+ writecontainer(current_module^.linkstaticlibs,iblinkstaticlibs,true,true);
|
|
|
+ current_ppu^.do_crc:=true;
|
|
|
+
|
|
|
+ current_ppu^.writeentry(ibendinterface);
|
|
|
+
|
|
|
+ { write the symtable entries }
|
|
|
+ inherited write;
|
|
|
+
|
|
|
+ { write dbx count }
|
|
|
+{$ifdef GDB}
|
|
|
+ if cs_gdb_dbx in aktglobalswitches then
|
|
|
+ begin
|
|
|
+{$IfDef EXTDEBUG}
|
|
|
+ writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
|
|
|
+{$ENDIF EXTDEBUG}
|
|
|
+ current_ppu^.putlongint(dbx_count);
|
|
|
+ current_ppu^.writeentry(ibdbxcount);
|
|
|
+ end;
|
|
|
+{$endif GDB}
|
|
|
+
|
|
|
+ current_ppu^.writeentry(ibendimplementation);
|
|
|
+
|
|
|
+ { write static symtable
|
|
|
+ needed for local debugging of unit functions }
|
|
|
+ if (current_module^.flags and uf_local_browser)<>0 then
|
|
|
+ psymtable(current_module^.localsymtable)^.write;
|
|
|
+ { write all browser section }
|
|
|
+ if (current_module^.flags and uf_has_browser)<>0 then
|
|
|
+ begin
|
|
|
+ current_ppu^.do_crc:=false; { doesn't affect crc }
|
|
|
+ write_browser;
|
|
|
+ pu:=pused_unit(current_module^.used_units.first);
|
|
|
+ while assigned(pu) do
|
|
|
+ begin
|
|
|
+ psymtable(pu^.u^.globalsymtable)^.write_browser;
|
|
|
+ pu:=pused_unit(pu^.next);
|
|
|
+ end;
|
|
|
+ current_ppu^.writeentry(ibendbrowser);
|
|
|
+ current_ppu^.do_crc:=true;
|
|
|
+ end;
|
|
|
+ if (current_module^.flags and uf_local_browser)<>0 then
|
|
|
+ psymtable(current_module^.localsymtable)^.write_browser;
|
|
|
+
|
|
|
+ { the last entry ibend is written automaticly }
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tunitsymtable.getnewtypecount : word;
|
|
|
+
|
|
|
+ begin
|
|
|
+{$ifdef GDB}
|
|
|
+ if not (cs_gdb_dbx in aktglobalswitches) then
|
|
|
+ getnewtypecount:=tsymtable.getnewtypecount
|
|
|
+ else
|
|
|
+{$endif GDB}
|
|
|
+ if symtabletype = staticsymtable then
|
|
|
+ getnewtypecount:=tsymtable.getnewtypecount
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ getnewtypecount:=unittypecount;
|
|
|
+ inc(unittypecount);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{$ifdef GDB}
|
|
|
+ {$ifndef STORENUMBER}
|
|
|
+ procedure tunitsymtable.orderdefs;
|
|
|
+ var
|
|
|
+ firstd, last, nonum, pd, cur, prev, lnext : pdef;
|
|
|
+
|
|
|
+ begin
|
|
|
+ pd:=rootdef;
|
|
|
+ firstd:=nil;
|
|
|
+ last:=nil;
|
|
|
+ nonum:=nil;
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ lnext:=pd^.next;
|
|
|
+ if pd^.globalnb > 0 then
|
|
|
+ if firstd = nil then
|
|
|
+ begin
|
|
|
+ firstd:=pd;
|
|
|
+ last:=pd;
|
|
|
+ last^.next:=nil;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ cur:=firstd;
|
|
|
+ prev:=nil;
|
|
|
+ while assigned(cur) and
|
|
|
+ (prev <> last) and
|
|
|
+ (cur^.globalnb>0) and
|
|
|
+ (cur^.globalnb<pd^.globalnb) do
|
|
|
+ begin
|
|
|
+ prev:=cur;
|
|
|
+ cur:=cur^.next;
|
|
|
+ end;
|
|
|
+ if cur = firstd then
|
|
|
+ begin
|
|
|
+ pd^.next:=firstd;
|
|
|
+ firstd:=pd;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ if prev = last then
|
|
|
+ begin
|
|
|
+ pd^.next:=nil;
|
|
|
+ last^.next:=pd;
|
|
|
+ last:=pd;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ pd^.next:=cur;
|
|
|
+ prev^.next:=pd;
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else { without number }
|
|
|
+ begin
|
|
|
+ pd^.next:=nonum;
|
|
|
+ nonum:=pd;
|
|
|
+ end;
|
|
|
+ pd:=lnext;
|
|
|
+ end;
|
|
|
+ if assigned(firstd) then
|
|
|
+ begin
|
|
|
+ rootdef:=firstd;
|
|
|
+ last^.next:=nonum;
|
|
|
+ end else
|
|
|
+ rootdef:=nonum;
|
|
|
+ end;
|
|
|
+ {$endif}
|
|
|
+
|
|
|
+ procedure tunitsymtable.concattypestabto(asmlist : paasmoutput);
|
|
|
+ var prev_dbx_count : plongint;
|
|
|
+ begin
|
|
|
+ if is_stab_written then exit;
|
|
|
+ if not assigned(name) then name := stringdup('Main_program');
|
|
|
+ if symtabletype = unitsymtable then
|
|
|
+ begin
|
|
|
+ unitid:=current_module^.unitcount;
|
|
|
+ inc(current_module^.unitcount);
|
|
|
+ end;
|
|
|
+ asmlist^.concat(new(pai_asm_comment,init(strpnew('Begin unit '+name^
|
|
|
+ +' has index '+tostr(unitid)))));
|
|
|
+ if cs_gdb_dbx in aktglobalswitches then
|
|
|
+ begin
|
|
|
+ if dbx_count_ok then
|
|
|
+ begin
|
|
|
+ asmlist^.insert(new(pai_asm_comment,init(strpnew('"repeated" unit '+name^
|
|
|
+ +' has index '+tostr(unitid)))));
|
|
|
+ do_count_dbx:=true;
|
|
|
+ asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
|
|
|
+ +tostr(N_EXCL)+',0,0,'+tostr(dbx_count)))));
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ prev_dbx_count := dbx_counter;
|
|
|
+ dbx_counter := nil;
|
|
|
+ if symtabletype = unitsymtable then
|
|
|
+ asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
|
|
|
+ +tostr(N_BINCL)+',0,0,0'))));
|
|
|
+ dbx_counter := @dbx_count;
|
|
|
+ end;
|
|
|
+ asmoutput:=asmlist;
|
|
|
+ {$ifdef tp}
|
|
|
+ foreach(concattypestab);
|
|
|
+ {$else}
|
|
|
+ foreach(@concattypestab);
|
|
|
+ {$endif}
|
|
|
+ if cs_gdb_dbx in aktglobalswitches then
|
|
|
+ begin
|
|
|
+ dbx_counter := prev_dbx_count;
|
|
|
+ do_count_dbx:=true;
|
|
|
+ asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
|
|
|
+ +tostr(N_EINCL)+',0,0,0'))));
|
|
|
+ dbx_count_ok := true;
|
|
|
+ end;
|
|
|
+ asmlist^.concat(new(pai_asm_comment,init(strpnew('End unit '+name^
|
|
|
+ +' has index '+tostr(unitid)))));
|
|
|
+ is_stab_written:=true;
|
|
|
+ end;
|
|
|
+{$endif}
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Definitions
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+{$I symdef.inc}
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Symbols
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+{$I symsym.inc}
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ GDB Helpers
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+{$ifdef GDB}
|
|
|
+ function typeglobalnumber(const s : string) : string;
|
|
|
+
|
|
|
+ var st : string;
|
|
|
+ symt : psymtable;
|
|
|
+ old_make_ref : boolean;
|
|
|
+ begin
|
|
|
+ old_make_ref:=make_ref;
|
|
|
+ make_ref:=false;
|
|
|
+ typeglobalnumber := '0';
|
|
|
+ srsym := nil;
|
|
|
+ if pos('.',s) > 0 then
|
|
|
+ begin
|
|
|
+ st := copy(s,1,pos('.',s)-1);
|
|
|
+ getsym(st,false);
|
|
|
+ st := copy(s,pos('.',s)+1,255);
|
|
|
+ if assigned(srsym) then
|
|
|
+ begin
|
|
|
+ if srsym^.typ = unitsym then
|
|
|
+ begin
|
|
|
+ symt := punitsym(srsym)^.unitsymtable;
|
|
|
+ srsym := symt^.search(st);
|
|
|
+ end else srsym := nil;
|
|
|
+ end;
|
|
|
+ end else st := s;
|
|
|
+ if srsym = nil then getsym(st,true);
|
|
|
+ if srsym^.typ<>typesym then
|
|
|
+ begin
|
|
|
+ Message(type_e_type_id_expected);
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ typeglobalnumber := ptypesym(srsym)^.definition^.numberstring;
|
|
|
+ make_ref:=old_make_ref;
|
|
|
+ end;
|
|
|
+{$endif GDB}
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Definition Helpers
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ procedure reset_global_defs;
|
|
|
+ var
|
|
|
+ def : pdef;
|
|
|
+{$ifdef debug}
|
|
|
+ prevdef : pdef;
|
|
|
+{$endif debug}
|
|
|
+ begin
|
|
|
+{$ifdef debug}
|
|
|
+ prevdef:=nil;
|
|
|
+{$endif debug}
|
|
|
+{$ifdef GDB}
|
|
|
+ pglobaltypecount:=@globaltypecount;
|
|
|
+{$endif GDB}
|
|
|
+ def:=firstglobaldef;
|
|
|
+ while assigned(def) do
|
|
|
+ begin
|
|
|
+{$ifdef GDB}
|
|
|
+ if assigned(def^.sym) then
|
|
|
+ def^.sym^.isusedinstab:=false;
|
|
|
+ def^.is_def_stab_written:=false;
|
|
|
+{$endif GDB}
|
|
|
+ {if not current_module^.in_implementation then}
|
|
|
+ begin
|
|
|
+ { reset rangenr's }
|
|
|
+ case def^.deftype of
|
|
|
+ orddef : porddef(def)^.rangenr:=0;
|
|
|
+ enumdef : penumdef(def)^.rangenr:=0;
|
|
|
+ arraydef : parraydef(def)^.rangenr:=0;
|
|
|
+ end;
|
|
|
+ if def^.deftype<>objectdef then
|
|
|
+ def^.has_rtti:=false;
|
|
|
+ def^.has_inittable:=false;
|
|
|
+ end;
|
|
|
+{$ifdef debug}
|
|
|
+ prevdef:=def;
|
|
|
+{$endif debug}
|
|
|
+ def:=def^.nextglobal;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Object Helpers
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ function search_class_member(pd : pobjectdef;const n : string) : psym;
|
|
|
+ { searches n in symtable of pd and all anchestors }
|
|
|
+ var
|
|
|
+ sym : psym;
|
|
|
+ begin
|
|
|
+ sym:=nil;
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ sym:=pd^.publicsyms^.search(n);
|
|
|
+ if assigned(sym) then
|
|
|
+ break;
|
|
|
+ pd:=pd^.childof;
|
|
|
+ end;
|
|
|
+ { this is needed for static methods in do_member_read pexpr unit PM
|
|
|
+ caused bug0214 }
|
|
|
+ if assigned(sym) then
|
|
|
+ begin
|
|
|
+ srsymtable:=pd^.publicsyms;
|
|
|
+ end;
|
|
|
+ search_class_member:=sym;
|
|
|
+ end;
|
|
|
+
|
|
|
+ var
|
|
|
+ _defaultprop : ppropertysym;
|
|
|
+
|
|
|
+ procedure testfordefaultproperty(p : {$ifdef STORENUMBER}pnamedindexobject{$else}psym{$endif});
|
|
|
+ begin
|
|
|
+ if (psym(p)^.typ=propertysym) and ((ppropertysym(p)^.options and ppo_defaultproperty)<>0) then
|
|
|
+ _defaultprop:=ppropertysym(p);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function search_default_property(pd : pobjectdef) : ppropertysym;
|
|
|
+ { returns the default property of a class, searches also anchestors }
|
|
|
+ begin
|
|
|
+ _defaultprop:=nil;
|
|
|
+ while assigned(pd) do
|
|
|
+ begin
|
|
|
+ {$ifdef tp}
|
|
|
+ pd^.publicsyms^.foreach(testfordefaultproperty);
|
|
|
+ {$else}
|
|
|
+ pd^.publicsyms^.foreach(@testfordefaultproperty);
|
|
|
+ {$endif}
|
|
|
+ if assigned(_defaultprop) then
|
|
|
+ break;
|
|
|
+ pd:=pd^.childof;
|
|
|
+ end;
|
|
|
+ search_default_property:=_defaultprop;
|
|
|
+ end;
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Macro's
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ procedure def_macro(const s : string);
|
|
|
+ var
|
|
|
+ mac : pmacrosym;
|
|
|
+ begin
|
|
|
+ mac:=pmacrosym(macros^.search(s));
|
|
|
+ if mac=nil then
|
|
|
+ begin
|
|
|
+ mac:=new(pmacrosym,init(s));
|
|
|
+ Message1(parser_m_macro_defined,mac^.name);
|
|
|
+ macros^.insert(mac);
|
|
|
+ end;
|
|
|
+ mac^.defined:=true;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure set_macro(const s : string;value : string);
|
|
|
+ var
|
|
|
+ mac : pmacrosym;
|
|
|
+ begin
|
|
|
+ mac:=pmacrosym(macros^.search(s));
|
|
|
+ if mac=nil then
|
|
|
+ begin
|
|
|
+ mac:=new(pmacrosym,init(s));
|
|
|
+ macros^.insert(mac);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ if assigned(mac^.buftext) then
|
|
|
+ freemem(mac^.buftext,mac^.buflen);
|
|
|
+ end;
|
|
|
+ Message2(parser_m_macro_set_to,mac^.name,value);
|
|
|
+ mac^.buflen:=length(value);
|
|
|
+ getmem(mac^.buftext,mac^.buflen);
|
|
|
+ move(value[1],mac^.buftext^,mac^.buflen);
|
|
|
+ mac^.defined:=true;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Symtable Stack
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+ procedure dellexlevel;
|
|
|
+ var
|
|
|
+ p : psymtable;
|
|
|
+ begin
|
|
|
+ p:=symtablestack;
|
|
|
+ symtablestack:=p^.next;
|
|
|
+ { symbol tables of unit interfaces are never disposed }
|
|
|
+ { this is handle by the unit unitm }
|
|
|
+ if not(p^.symtabletype in [unitsymtable,globalsymtable,stt_exceptsymtable]) or dispose_global then
|
|
|
+ dispose(p,done);
|
|
|
+ end;
|
|
|
+
|
|
|
+{$ifdef DEBUG}
|
|
|
+ procedure test_symtablestack;
|
|
|
+ var
|
|
|
+ p : psymtable;
|
|
|
+ i : longint;
|
|
|
+ begin
|
|
|
+ p:=symtablestack;
|
|
|
+ i:=0;
|
|
|
+ while assigned(p) do
|
|
|
+ begin
|
|
|
+ inc(i);
|
|
|
+ p:=p^.next;
|
|
|
+ if i>500 then
|
|
|
+ Message(sym_f_internal_error_in_symtablestack);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure list_symtablestack;
|
|
|
+ var
|
|
|
+ p : psymtable;
|
|
|
+ i : longint;
|
|
|
+ begin
|
|
|
+ p:=symtablestack;
|
|
|
+ i:=0;
|
|
|
+ while assigned(p) do
|
|
|
+ begin
|
|
|
+ inc(i);
|
|
|
+ writeln(i,' ',p^.name^);
|
|
|
+ p:=p^.next;
|
|
|
+ if i>500 then
|
|
|
+ Message(sym_f_internal_error_in_symtablestack);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+{$endif DEBUG}
|
|
|
+
|
|
|
+
|
|
|
+{****************************************************************************
|
|
|
+ Init/Done Symtable
|
|
|
+****************************************************************************}
|
|
|
+
|
|
|
+{$ifdef tp}
|
|
|
+ procedure do_streamerror;
|
|
|
+ begin
|
|
|
+ if symbolstream.status=-2 then
|
|
|
+ WriteLn('Error: Not enough EMS memory')
|
|
|
+ else
|
|
|
+ WriteLn('Error: EMS Error ',symbolstream.status);
|
|
|
+ halt(1);
|
|
|
+ end;
|
|
|
+{$endif TP}
|
|
|
+
|
|
|
+ procedure InitSymtable;
|
|
|
+ begin
|
|
|
+{$ifdef TP}
|
|
|
+ { Allocate stream }
|
|
|
+ if use_big then
|
|
|
+ begin
|
|
|
+ streamerror:=@do_streamerror;
|
|
|
+ { symbolstream.init('TMPFILE',stcreate,16000); }
|
|
|
+ {$ifndef dpmi}
|
|
|
+ symbolstream.init(10000,4000000); {using ems streams}
|
|
|
+ {$else}
|
|
|
+ symbolstream.init(1000000,16000); {using memory streams}
|
|
|
+ {$endif}
|
|
|
+ if symbolstream.errorinfo=stiniterror then
|
|
|
+ do_streamerror;
|
|
|
+ { write something, because pos 0 means nil pointer }
|
|
|
+ symbolstream.writestr(@inputfile);
|
|
|
+ end;
|
|
|
+{$endif tp}
|
|
|
+ { Reset symbolstack }
|
|
|
+ registerdef:=false;
|
|
|
+ read_member:=false;
|
|
|
+ symtablestack:=nil;
|
|
|
+ systemunit:=nil;
|
|
|
+ objpasunit:=nil;
|
|
|
+ sroot:=nil;
|
|
|
+{$ifdef GDB}
|
|
|
+ firstglobaldef:=nil;
|
|
|
+ lastglobaldef:=nil;
|
|
|
+{$endif GDB}
|
|
|
+ globaltypecount:=1;
|
|
|
+ pglobaltypecount:=@globaltypecount;
|
|
|
+ { create error syms and def }
|
|
|
+ generrorsym:=new(perrorsym,init);
|
|
|
+ generrordef:=new(perrordef,init);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure DoneSymtable;
|
|
|
+ begin
|
|
|
+ dispose(generrorsym,done);
|
|
|
+ dispose(generrordef,done);
|
|
|
+ { unload all symtables
|
|
|
+ done with loaded_units
|
|
|
+ dispose_global:=true;
|
|
|
+ while assigned(symtablestack) do
|
|
|
+ dellexlevel; }
|
|
|
+{$ifdef TP}
|
|
|
+ { close the stream }
|
|
|
+ if use_big then
|
|
|
+ symbolstream.done;
|
|
|
+{$endif}
|
|
|
+ end;
|
|
|
+
|
|
|
+end.
|
|
|
+{
|
|
|
+ $Log$
|
|
|
+ Revision 1.1 1999-04-26 14:50:13 michael
|
|
|
+ + Added my version again after crash
|
|
|
+
|
|
|
+ Revision 1.150 1999/04/25 17:36:13 peter
|
|
|
+ * typo fix for storenumber
|
|
|
+
|
|
|
+ Revision 1.149 1999/04/21 22:05:28 pierre
|
|
|
+ + tsymtable.find_at_offset function
|
|
|
+ used by ra386att to give arg name from ebp offset with -vz option
|
|
|
+
|
|
|
+ Revision 1.148 1999/04/21 16:31:44 pierre
|
|
|
+ ra386att.pas : commit problem !
|
|
|
+
|
|
|
+ Revision 1.147 1999/04/21 09:43:57 peter
|
|
|
+ * storenumber works
|
|
|
+ * fixed some typos in double_checksum
|
|
|
+ + incompatible types type1 and type2 message (with storenumber)
|
|
|
+
|
|
|
+ Revision 1.146 1999/04/19 09:33:14 pierre
|
|
|
+ + added tsymtable.set_alignment(longint) function
|
|
|
+ to change the offsets of all function args
|
|
|
+ if declared as cdecl or stdcall
|
|
|
+ (this must be done after because the cdecl is parsed after
|
|
|
+ insertion of the function parameterss into parast symboltable)
|
|
|
+
|
|
|
+ Revision 1.145 1999/04/17 13:16:24 peter
|
|
|
+ * fixes for storenumber
|
|
|
+
|
|
|
+ Revision 1.144 1999/04/15 10:01:45 peter
|
|
|
+ * small update for storenumber
|
|
|
+
|
|
|
+ Revision 1.143 1999/04/14 09:15:04 peter
|
|
|
+ * first things to store the symbol/def number in the ppu
|
|
|
+
|
|
|
+ Revision 1.142 1999/04/08 14:54:10 pierre
|
|
|
+ * suppression of val para unused warnings
|
|
|
+
|
|
|
+ Revision 1.141 1999/04/07 15:31:09 pierre
|
|
|
+ * all formaldefs are now a sinlge definition
|
|
|
+ cformaldef (this was necessary for double_checksum)
|
|
|
+ + small part of double_checksum code
|
|
|
+
|
|
|
+ Revision 1.140 1999/03/31 13:55:24 peter
|
|
|
+ * assembler inlining working for ag386bin
|
|
|
+
|
|
|
+ Revision 1.139 1999/03/24 23:17:30 peter
|
|
|
+ * fixed bugs 212,222,225,227,229,231,233
|
|
|
+
|
|
|
+ Revision 1.138 1999/03/21 22:49:11 florian
|
|
|
+ * private ids of objects can be reused in child classes
|
|
|
+ if they are in another unit
|
|
|
+
|
|
|
+ Revision 1.137 1999/03/17 22:23:20 florian
|
|
|
+ * a FPC compiled compiler checks now also in debug mode in assigned
|
|
|
+ if a pointer points to the heap
|
|
|
+ * when a symtable is loaded, there is no need to check for duplicate
|
|
|
+ symbols. This leads to crashes because defowner isn't assigned
|
|
|
+ in this case
|
|
|
+
|
|
|
+ Revision 1.136 1999/03/01 13:45:07 pierre
|
|
|
+ + added staticppusymtable symtable type for local browsing
|
|
|
+
|
|
|
+ Revision 1.135 1999/02/23 18:29:28 pierre
|
|
|
+ * win32 compilation error fix
|
|
|
+ + some work for local browser (not cl=omplete yet)
|
|
|
+
|
|
|
+ Revision 1.134 1999/02/22 15:09:42 florian
|
|
|
+ * behaviaor of PROTECTED and PRIVATE fixed, works now like TP/Delphi
|
|
|
+
|
|
|
+ Revision 1.133 1999/02/22 13:07:12 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.132 1999/02/22 02:15:40 peter
|
|
|
+ * updates for ag386bin
|
|
|
+
|
|
|
+ Revision 1.131 1999/02/16 00:44:34 peter
|
|
|
+ * tp7 fix, assigned() can only be used on vars, not on functions
|
|
|
+
|
|
|
+ Revision 1.130 1999/02/15 13:13:16 pierre
|
|
|
+ * fix for bug0216
|
|
|
+
|
|
|
+ Revision 1.129 1999/02/11 09:46:29 pierre
|
|
|
+ * fix for normal method calls inside static methods :
|
|
|
+ WARNING there were both parser and codegen errors !!
|
|
|
+ added static_call boolean to calln tree
|
|
|
+
|
|
|
+ Revision 1.128 1999/02/09 23:03:05 florian
|
|
|
+ * check for duplicate field names in inherited classes/objects
|
|
|
+ * bug with self from the mailing list solved (the problem
|
|
|
+ was that classes were sometimes pushed wrong)
|
|
|
+
|
|
|
+ Revision 1.127 1999/02/08 11:29:06 pierre
|
|
|
+ * fix for bug0214
|
|
|
+ several problems where combined
|
|
|
+ search_class_member did not set srsymtable
|
|
|
+ => in do_member_read the call node got a wrong symtable
|
|
|
+ in cg386cal the vmt was pushed twice without chacking if it exists
|
|
|
+ now %esi is set to zero and pushed if not vmt
|
|
|
+ (not very efficient but should work !)
|
|
|
+
|
|
|
+ Revision 1.126 1999/02/05 08:54:31 pierre
|
|
|
+ + linkofiles splitted inot linkofiles and linkunitfiles
|
|
|
+ because linkofiles must be stored with directory
|
|
|
+ to enabled linking of different objects with same name
|
|
|
+ in a different directory
|
|
|
+
|
|
|
+ Revision 1.125 1999/02/03 09:44:33 pierre
|
|
|
+ * symbol nubering begins with 1 in number_symbols
|
|
|
+ * program tmodule has globalsymtable for its staticsymtable
|
|
|
+ (to get it displayed in IDE globals list)
|
|
|
+ + list of symbol (browcol) greatly improved for IDE
|
|
|
+
|
|
|
+ Revision 1.124 1999/01/27 12:58:33 pierre
|
|
|
+ * unused var warning suppressed for high of open arrays
|
|
|
+
|
|
|
+ Revision 1.123 1999/01/21 16:41:03 pierre
|
|
|
+ * fix for constructor inside with statements
|
|
|
+
|
|
|
+ Revision 1.122 1999/01/20 10:16:44 peter
|
|
|
+ * don't update crc when writing objs,libs and sources
|
|
|
+
|
|
|
+ Revision 1.121 1999/01/14 21:50:00 peter
|
|
|
+ * fixed forwardpointer problem with multiple forwards for the same
|
|
|
+ typesym. It now uses a linkedlist instead of a single pointer
|
|
|
+
|
|
|
+ Revision 1.120 1999/01/13 14:29:22 daniel
|
|
|
+ * nonextfield repaired
|
|
|
+
|
|
|
+ Revision 1.119 1999/01/12 14:25:38 peter
|
|
|
+ + BrowserLog for browser.log generation
|
|
|
+ + BrowserCol for browser info in TCollections
|
|
|
+ * released all other UseBrowser
|
|
|
+
|
|
|
+ Revision 1.118 1999/01/05 08:20:10 florian
|
|
|
+ * mainly problem with invalid case ranges fixed (reported by Jonas)
|
|
|
+
|
|
|
+ Revision 1.117 1998/12/30 22:15:57 peter
|
|
|
+ + farpointer type
|
|
|
+ * absolutesym now also stores if its far
|
|
|
+
|
|
|
+ Revision 1.116 1998/12/30 13:41:16 peter
|
|
|
+ * released valuepara
|
|
|
+
|
|
|
+ Revision 1.115 1998/12/11 00:03:48 peter
|
|
|
+ + globtype,tokens,version unit splitted from globals
|
|
|
+
|
|
|
+ Revision 1.114 1998/12/10 09:47:29 florian
|
|
|
+ + basic operations with int64/qord (compiler with -dint64)
|
|
|
+ + rtti of enumerations extended: names are now written
|
|
|
+
|
|
|
+ Revision 1.113 1998/12/08 10:18:17 peter
|
|
|
+ + -gh for heaptrc unit
|
|
|
+
|
|
|
+ Revision 1.112 1998/12/04 10:18:10 florian
|
|
|
+ * some stuff for procedures of object added
|
|
|
+ * bug with overridden virtual constructors fixed (reported by Italo Gomes)
|
|
|
+
|
|
|
+ Revision 1.111 1998/11/30 16:34:46 pierre
|
|
|
+ * corrected problems with rangecheck
|
|
|
+ + added needed code for no rangecheck in CRC32 functions in ppu unit
|
|
|
+ * enumdef lso need its rangenr reset to zero
|
|
|
+ when calling reset_global_defs
|
|
|
+
|
|
|
+ Revision 1.110 1998/11/28 16:20:58 peter
|
|
|
+ + support for dll variables
|
|
|
+
|
|
|
+ Revision 1.109 1998/11/27 14:50:49 peter
|
|
|
+ + open strings, $P switch support
|
|
|
+
|
|
|
+ Revision 1.108 1998/11/24 23:00:32 peter
|
|
|
+ * small crash prevention
|
|
|
+
|
|
|
+ Revision 1.107 1998/11/20 15:36:01 florian
|
|
|
+ * problems with rtti fixed, hope it works
|
|
|
+
|
|
|
+ Revision 1.106 1998/11/18 15:44:20 peter
|
|
|
+ * VALUEPARA for tp7 compatible value parameters
|
|
|
+
|
|
|
+ Revision 1.105 1998/11/17 10:39:18 peter
|
|
|
+ * has_rtti,has_inittable reset
|
|
|
+
|
|
|
+ Revision 1.104 1998/11/16 10:13:52 peter
|
|
|
+ * label defines are checked at the end of the proc
|
|
|
+
|
|
|
+ Revision 1.103 1998/11/13 15:40:32 pierre
|
|
|
+ + added -Se in Makefile cvstest target
|
|
|
+ + lexlevel cleanup
|
|
|
+ normal_function_level main_program_level and unit_init_level defined
|
|
|
+ * tins_cache grown to A_EMMS (gave range check error in asm readers)
|
|
|
+ (test added in code !)
|
|
|
+ * -Un option was wrong
|
|
|
+ * _FAIL and _SELF only keyword inside
|
|
|
+ constructors and methods respectively
|
|
|
+
|
|
|
+ Revision 1.102 1998/11/12 16:43:34 florian
|
|
|
+ * functions with ansi strings as result didn't work, solved
|
|
|
+
|
|
|
+ Revision 1.101 1998/11/12 12:55:18 pierre
|
|
|
+ * fix for bug0176 and bug0177
|
|
|
+
|
|
|
+ Revision 1.100 1998/11/10 10:09:15 peter
|
|
|
+ * va_list -> array of const
|
|
|
+
|
|
|
+ Revision 1.99 1998/11/09 11:44:38 peter
|
|
|
+ + va_list for printf support
|
|
|
+
|
|
|
+ Revision 1.98 1998/11/05 23:33:35 peter
|
|
|
+ * symtable.done sets vars to nil
|
|
|
+
|
|
|
+ Revision 1.97 1998/11/05 12:03:00 peter
|
|
|
+ * released useansistring
|
|
|
+ * removed -Sv, its now available in fpc modes
|
|
|
+
|
|
|
+ Revision 1.96 1998/10/28 18:26:19 pierre
|
|
|
+ * removed some erros after other errors (introduced by useexcept)
|
|
|
+ * stabs works again correctly (for how long !)
|
|
|
+
|
|
|
+ Revision 1.95 1998/10/21 08:40:01 florian
|
|
|
+ + ansistring operator +
|
|
|
+ + $h and string[n] for n>255 added
|
|
|
+ * small problem with TP fixed
|
|
|
+
|
|
|
+ Revision 1.94 1998/10/20 08:07:03 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.93 1998/10/19 08:55:08 pierre
|
|
|
+ * wrong stabs info corrected once again !!
|
|
|
+ + variable vmt offset with vmt field only if required
|
|
|
+ implemented now !!!
|
|
|
+
|
|
|
+ Revision 1.92 1998/10/16 13:12:56 pierre
|
|
|
+ * added vmt_offsets in destructors code also !!!
|
|
|
+ * vmt_offset code for m68k
|
|
|
+
|
|
|
+ Revision 1.91 1998/10/16 08:48:38 peter
|
|
|
+ * fixed some misplaced $endif GDB
|
|
|
+
|
|
|
+ Revision 1.90 1998/10/15 15:13:32 pierre
|
|
|
+ + added oo_hasconstructor and oo_hasdestructor
|
|
|
+ for objects options
|
|
|
+
|
|
|
+ Revision 1.89 1998/10/14 13:38:25 peter
|
|
|
+ * fixed path with staticlib/objects in ppufiles
|
|
|
+
|
|
|
+ Revision 1.88 1998/10/09 16:36:07 pierre
|
|
|
+ * some memory leaks specific to usebrowser define fixed
|
|
|
+ * removed tmodule.implsymtable (was like tmodule.localsymtable)
|
|
|
+
|
|
|
+ Revision 1.87 1998/10/09 11:47:57 pierre
|
|
|
+ * still more memory leaks fixes !!
|
|
|
+
|
|
|
+ Revision 1.86 1998/10/08 17:17:35 pierre
|
|
|
+ * current_module old scanner tagged as invalid if unit is recompiled
|
|
|
+ + added ppheap for better info on tracegetmem of heaptrc
|
|
|
+ (adds line column and file index)
|
|
|
+ * several memory leaks removed ith help of heaptrc !!
|
|
|
+
|
|
|
+ Revision 1.85 1998/10/08 13:48:51 peter
|
|
|
+ * fixed memory leaks for do nothing source
|
|
|
+ * fixed unit interdependency
|
|
|
+
|
|
|
+ Revision 1.84 1998/10/06 17:16:58 pierre
|
|
|
+ * some memory leaks fixed (thanks to Peter for heaptrc !)
|
|
|
+
|
|
|
+ Revision 1.83 1998/09/26 17:45:45 peter
|
|
|
+ + idtoken and only one token table
|
|
|
+
|
|
|
+ Revision 1.82 1998/09/25 09:52:57 peter
|
|
|
+ + store also datasize and # of symbols in ppu
|
|
|
+ * # of defs is now also stored in structs
|
|
|
+
|
|
|
+ Revision 1.81 1998/09/24 23:49:21 peter
|
|
|
+ + aktmodeswitches
|
|
|
+
|
|
|
+ Revision 1.80 1998/09/23 12:20:51 pierre
|
|
|
+ * main program tmodule had no symtable (crashed browser)
|
|
|
+ * unit symbols problem fixed !!
|
|
|
+
|
|
|
+ Revision 1.79 1998/09/23 12:03:57 peter
|
|
|
+ * overloading fix for array of const
|
|
|
+
|
|
|
+ Revision 1.78 1998/09/22 17:13:54 pierre
|
|
|
+ + browsing updated and developed
|
|
|
+ records and objects fields are also stored
|
|
|
+
|
|
|
+ Revision 1.77 1998/09/22 15:37:24 peter
|
|
|
+ + array of const start
|
|
|
+
|
|
|
+ Revision 1.76 1998/09/21 10:00:08 peter
|
|
|
+ * store number of defs in ppu file
|
|
|
+
|
|
|
+ Revision 1.75 1998/09/21 08:58:31 peter
|
|
|
+ + speedsearch, which also needs speedvalue as parameter
|
|
|
+
|
|
|
+ Revision 1.74 1998/09/21 08:45:25 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.73 1998/09/20 09:38:47 florian
|
|
|
+ * hasharray for defs fixed
|
|
|
+ * ansistring code generation corrected (init/final, assignement)
|
|
|
+
|
|
|
+ Revision 1.72 1998/09/19 22:56:18 florian
|
|
|
+ + hash table for getdefnr added
|
|
|
+
|
|
|
+ Revision 1.71 1998/09/18 08:01:40 pierre
|
|
|
+ + improvement on the usebrowser part
|
|
|
+ (does not work correctly for now)
|
|
|
+
|
|
|
+ Revision 1.70 1998/09/09 11:50:57 pierre
|
|
|
+ * forward def are not put in record or objects
|
|
|
+ + added check for forwards also in record and objects
|
|
|
+ * dummy parasymtable for unit initialization removed from
|
|
|
+ symtable stack
|
|
|
+
|
|
|
+ Revision 1.69 1998/09/07 23:10:25 florian
|
|
|
+ * a lot of stuff fixed regarding rtti and publishing of properties,
|
|
|
+ basics should now work
|
|
|
+
|
|
|
+ Revision 1.68 1998/09/07 19:33:26 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.67 1998/09/07 18:46:14 peter
|
|
|
+ * update smartlinking, uses getdatalabel
|
|
|
+ * renamed ptree.value vars to value_str,value_real,value_set
|
|
|
+
|
|
|
+ Revision 1.66 1998/09/07 17:37:05 florian
|
|
|
+ * first fixes for published properties
|
|
|
+
|
|
|
+ Revision 1.65 1998/09/06 22:42:03 florian
|
|
|
+ + rtti genreation for properties added
|
|
|
+
|
|
|
+ Revision 1.64 1998/09/05 22:11:04 florian
|
|
|
+ + switch -vb
|
|
|
+ * while/repeat loops accept now also word/longbool conditions
|
|
|
+ * makebooltojump did an invalid ungetregister32, fixed
|
|
|
+
|
|
|
+ Revision 1.63 1998/09/04 17:34:23 pierre
|
|
|
+ * bug with datalabel corrected
|
|
|
+ + assembler errors better commented
|
|
|
+ * one nested record crash removed
|
|
|
+
|
|
|
+ Revision 1.62 1998/09/04 08:42:10 peter
|
|
|
+ * updated some error messages
|
|
|
+
|
|
|
+ Revision 1.61 1998/09/03 16:03:21 florian
|
|
|
+ + rtti generation
|
|
|
+ * init table generation changed
|
|
|
+
|
|
|
+ Revision 1.60 1998/09/01 17:39:52 peter
|
|
|
+ + internal constant functions
|
|
|
+
|
|
|
+ Revision 1.59 1998/09/01 12:53:27 peter
|
|
|
+ + aktpackenum
|
|
|
+
|
|
|
+ Revision 1.58 1998/09/01 07:54:26 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.57 1998/08/31 12:26:33 peter
|
|
|
+ * m68k and palmos updates from surebugfixes
|
|
|
+
|
|
|
+ Revision 1.56 1998/08/21 14:08:55 pierre
|
|
|
+ + TEST_FUNCRET now default (old code removed)
|
|
|
+ works also for m68k (at least compiles)
|
|
|
+
|
|
|
+ Revision 1.55 1998/08/21 08:43:32 pierre
|
|
|
+ * pocdecl and poclearstack are now different
|
|
|
+ external must but written as last specification
|
|
|
+
|
|
|
+ Revision 1.54 1998/08/20 09:26:48 pierre
|
|
|
+ + funcret setting in underproc testing
|
|
|
+ compile with _dTEST_FUNCRET
|
|
|
+
|
|
|
+ Revision 1.53 1998/08/19 18:04:56 peter
|
|
|
+ * fixed current_module^.in_implementation flag
|
|
|
+
|
|
|
+ Revision 1.51 1998/08/18 14:17:12 pierre
|
|
|
+ * bug about assigning the return value of a function to
|
|
|
+ a procvar fixed : warning
|
|
|
+ assigning a proc to a procvar need @ in FPC mode !!
|
|
|
+ * missing file/line info restored
|
|
|
+
|
|
|
+ Revision 1.50 1998/08/17 10:10:13 peter
|
|
|
+ - removed OLDPPU
|
|
|
+
|
|
|
+ Revision 1.49 1998/08/12 19:39:31 peter
|
|
|
+ * fixed some crashes
|
|
|
+
|
|
|
+ Revision 1.48 1998/08/10 14:50:32 peter
|
|
|
+ + localswitches, moduleswitches, globalswitches splitting
|
|
|
+
|
|
|
+ Revision 1.47 1998/08/10 10:00:19 peter
|
|
|
+ * Moved symbolstream to symtable.pas
|
|
|
+
|
|
|
+ Revision 1.46 1998/08/08 10:19:19 florian
|
|
|
+ * small fixes to write the extended type correct
|
|
|
+
|
|
|
+ Revision 1.45 1998/08/02 16:42:00 florian
|
|
|
+ * on o : tobject do should also work now, the exceptsymtable shouldn't be
|
|
|
+ disposed by dellexlevel
|
|
|
+
|
|
|
+ Revision 1.44 1998/07/30 11:18:21 florian
|
|
|
+ + first implementation of try ... except on .. do end;
|
|
|
+ * limitiation of 65535 bytes parameters for cdecl removed
|
|
|
+
|
|
|
+ Revision 1.43 1998/07/28 21:52:56 florian
|
|
|
+ + implementation of raise and try..finally
|
|
|
+ + some misc. exception stuff
|
|
|
+
|
|
|
+ Revision 1.42 1998/07/20 10:23:03 florian
|
|
|
+ * better ansi string assignement
|
|
|
+
|
|
|
+ Revision 1.41 1998/07/18 22:54:31 florian
|
|
|
+ * some ansi/wide/longstring support fixed:
|
|
|
+ o parameter passing
|
|
|
+ o returning as result from functions
|
|
|
+
|
|
|
+ Revision 1.40 1998/07/14 14:47:09 peter
|
|
|
+ * released NEWINPUT
|
|
|
+
|
|
|
+ Revision 1.39 1998/07/10 00:00:06 peter
|
|
|
+ * fixed ttypesym bug finally
|
|
|
+ * fileinfo in the symtable and better using for unused vars
|
|
|
+
|
|
|
+ Revision 1.38 1998/07/07 11:20:17 peter
|
|
|
+ + NEWINPUT for a better inputfile and scanner object
|
|
|
+
|
|
|
+ Revision 1.37 1998/06/24 14:48:42 peter
|
|
|
+ * ifdef newppu -> ifndef oldppu
|
|
|
+
|
|
|
+ Revision 1.36 1998/06/17 14:10:19 peter
|
|
|
+ * small os2 fixes
|
|
|
+ * fixed interdependent units with newppu (remake3 under linux works now)
|
|
|
+
|
|
|
+ Revision 1.35 1998/06/16 08:56:35 peter
|
|
|
+ + targetcpu
|
|
|
+ * cleaner pmodules for newppu
|
|
|
+
|
|
|
+ Revision 1.34 1998/06/15 15:38:12 pierre
|
|
|
+ * small bug in systems.pas corrected
|
|
|
+ + operators in different units better hanlded
|
|
|
+
|
|
|
+ Revision 1.33 1998/06/15 14:10:53 daniel
|
|
|
+ * File was ruined, fixed.
|
|
|
+
|
|
|
+ Revision 1.31 1998/06/13 00:10:20 peter
|
|
|
+ * working browser and newppu
|
|
|
+ * some small fixes against crashes which occured in bp7 (but not in
|
|
|
+ fpc?!)
|
|
|
+
|
|
|
+ Revision 1.30 1998/06/09 16:01:53 pierre
|
|
|
+ + added procedure directive parsing for procvars
|
|
|
+ (accepted are popstack cdecl and pascal)
|
|
|
+ + added C vars with the following syntax
|
|
|
+ var C calias 'true_c_name';(can be followed by external)
|
|
|
+ reason is that you must add the Cprefix
|
|
|
+
|
|
|
+ which is target dependent
|
|
|
+
|
|
|
+ Revision 1.29 1998/06/07 15:30:26 florian
|
|
|
+ + first working rtti
|
|
|
+ + data init/final. for local variables
|
|
|
+
|
|
|
+ Revision 1.28 1998/06/06 09:27:39 peter
|
|
|
+ * new depend file generated
|
|
|
+
|
|
|
+ Revision 1.27 1998/06/05 14:37:38 pierre
|
|
|
+ * fixes for inline for operators
|
|
|
+ * inline procedure more correctly restricted
|
|
|
+
|
|
|
+ Revision 1.26 1998/06/04 23:52:03 peter
|
|
|
+ * m68k compiles
|
|
|
+ + .def file creation moved to gendef.pas so it could also be used
|
|
|
+ for win32
|
|
|
+
|
|
|
+ Revision 1.25 1998/06/04 09:55:48 pierre
|
|
|
+ * demangled name of procsym reworked to become independant of the
|
|
|
+ mangling scheme
|
|
|
+
|
|
|
+ Revision 1.24 1998/06/03 22:49:04 peter
|
|
|
+ + wordbool,longbool
|
|
|
+ * rename bis,von -> high,low
|
|
|
+ * moved some systemunit loading/creating to psystem.pas
|
|
|
+
|
|
|
+ Revision 1.23 1998/05/28 14:40:30 peter
|
|
|
+ * fixes for newppu, remake3 works now with it
|
|
|
+
|
|
|
+ Revision 1.22 1998/05/27 19:45:09 peter
|
|
|
+ * symtable.pas splitted into includefiles
|
|
|
+ * symtable adapted for $ifndef OLDPPU
|
|
|
+
|
|
|
+ Revision 1.21 1998/05/23 01:21:31 peter
|
|
|
+ + aktasmmode, aktoptprocessor, aktoutputformat
|
|
|
+ + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
|
|
|
+ + $LIBNAME to set the library name where the unit will be put in
|
|
|
+ * splitted cgi386 a bit (codeseg to large for bp7)
|
|
|
+ * nasm, tasm works again. nasm moved to ag386nsm.pas
|
|
|
+
|
|
|
+ Revision 1.20 1998/05/21 19:33:37 peter
|
|
|
+ + better procedure directive handling and only one table
|
|
|
+
|
|
|
+ Revision 1.19 1998/05/20 09:42:37 pierre
|
|
|
+ + UseTokenInfo now default
|
|
|
+ * unit in interface uses and implementation uses gives error now
|
|
|
+ * only one error for unknown symbol (uses lastsymknown boolean)
|
|
|
+ the problem came from the label code !
|
|
|
+ + first inlined procedures and function work
|
|
|
+ (warning there might be allowed cases were the result is still wrong !!)
|
|
|
+ * UseBrower updated gives a global list of all position of all used symbols
|
|
|
+ with switch -gb
|
|
|
+
|
|
|
+ Revision 1.18 1998/05/11 13:07:57 peter
|
|
|
+ + $ifndef OLDPPU for the new ppuformat
|
|
|
+ + $define GDB not longer required
|
|
|
+ * removed all warnings and stripped some log comments
|
|
|
+ * no findfirst/findnext anymore to remove smartlink *.o files
|
|
|
+
|
|
|
+ Revision 1.17 1998/05/06 08:38:48 pierre
|
|
|
+ * better position info with UseTokenInfo
|
|
|
+ UseTokenInfo greatly simplified
|
|
|
+ + added check for changed tree after first time firstpass
|
|
|
+ (if we could remove all the cases were it happen
|
|
|
+ we could skip all firstpass if firstpasscount > 1)
|
|
|
+ Only with ExtDebug
|
|
|
+
|
|
|
+ Revision 1.16 1998/05/05 15:24:20 michael
|
|
|
+ * Fix to save units with classes.
|
|
|
+
|
|
|
+ Revision 1.15 1998/05/04 17:54:29 peter
|
|
|
+ + smartlinking works (only case jumptable left todo)
|
|
|
+ * redesign of systems.pas to support assemblers and linkers
|
|
|
+ + Unitname is now also in the PPU-file, increased version to 14
|
|
|
+
|
|
|
+ Revision 1.14 1998/05/01 16:38:46 florian
|
|
|
+ * handling of private and protected fixed
|
|
|
+ + change_keywords_to_tp implemented to remove
|
|
|
+ keywords which aren't supported by tp
|
|
|
+ * break and continue are now symbols of the system unit
|
|
|
+ + widestring, longstring and ansistring type released
|
|
|
+
|
|
|
+ Revision 1.13 1998/05/01 09:01:25 florian
|
|
|
+ + correct semantics of private and protected
|
|
|
+ * small fix in variable scope:
|
|
|
+ a id can be used in a parameter list of a method, even it is used in
|
|
|
+ an anchestor class as field id
|
|
|
+
|
|
|
+ Revision 1.12 1998/05/01 07:43:57 florian
|
|
|
+ + basics for rtti implemented
|
|
|
+ + switch $m (generate rtti for published sections)
|
|
|
+
|
|
|
+ Revision 1.11 1998/04/30 15:59:42 pierre
|
|
|
+ * GDB works again better :
|
|
|
+ correct type info in one pass
|
|
|
+ + UseTokenInfo for better source position
|
|
|
+ * fixed one remaining bug in scanner for line counts
|
|
|
+ * several little fixes
|
|
|
+
|
|
|
+ Revision 1.10 1998/04/29 10:34:05 pierre
|
|
|
+ + added some code for ansistring (not complete nor working yet)
|
|
|
+ * corrected operator overloading
|
|
|
+ * corrected nasm output
|
|
|
+ + started inline procedures
|
|
|
+ + added starstarn : use ** for exponentiation (^ gave problems)
|
|
|
+ + started UseTokenInfo cond to get accurate positions
|
|
|
+
|
|
|
+ Revision 1.9 1998/04/27 23:10:29 peter
|
|
|
+ + new scanner
|
|
|
+ * $makelib -> if smartlink
|
|
|
+ * small filename fixes pmodule.setfilename
|
|
|
+ * moved import from files.pas -> import.pas
|
|
|
+
|
|
|
+ Revision 1.8 1998/04/21 10:16:48 peter
|
|
|
+ * patches from strasbourg
|
|
|
+ * objects is not used anymore in the fpc compiled version
|
|
|
+
|
|
|
+ Revision 1.7 1998/04/13 22:20:36 florian
|
|
|
+ + stricter checking for duplicate id, solves also bug0097
|
|
|
+
|
|
|
+ Revision 1.6 1998/04/13 17:20:43 florian
|
|
|
+ * tdef.done much faster implemented
|
|
|
+
|
|
|
+ Revision 1.5 1998/04/10 21:36:56 florian
|
|
|
+ + some stuff to support method pointers (procedure of object) added
|
|
|
+ (declaration, parameter handling)
|
|
|
+
|
|
|
+ Revision 1.4 1998/04/08 16:58:08 pierre
|
|
|
+ * several bugfixes
|
|
|
+ ADD ADC and AND are also sign extended
|
|
|
+ nasm output OK (program still crashes at end
|
|
|
+ and creates wrong assembler files !!)
|
|
|
+ procsym types sym in tdef removed !!
|
|
|
+
|
|
|
+ Revision 1.3 1998/04/07 13:19:52 pierre
|
|
|
+ * bugfixes for reset_gdb_info
|
|
|
+ in MEM parsing for go32v2
|
|
|
+ better external symbol creation
|
|
|
+ support for rhgdb.exe (lowercase file names)
|
|
|
+
|
|
|
+ Revision 1.2 1998/04/06 13:09:04 daniel
|
|
|
+ * Emergency solution for bug in reset_gdb_info.
|
|
|
+}
|