123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- {
- $Id$
- This unit implements the different types of symbol tables
- Copyright (C) 1998-2000 by Daniel Mantione,
- member of the Free Pascal development team
- 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 symtablt;
- interface
- uses objects,cobjects,symtable,globtype;
- type Pglobalsymtable=^Tglobalsymtable;
- Pinterfacesymtable=^Tinterfacesymtable;
- Pimplsymtable=^Tsymtable;
- Pprocsymtable=^Tprocsymtable;
- Punitsymtable=^Tunitsymtable;
- Pobjectsymtable=^Tobjectsymtable;
- Tglobalsymtable=object(Tcontainingsymtable)
- constructor init;
- {Checks if all used units are used.}
- procedure check_units;
- function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
- function varsymtodata(sym:Psym;len:longint):longint;virtual;
- end;
- Tinterfacesymtable=object(Tglobalsymtable)
- unitid:word;
- function varsymprefix:string;virtual;
- end;
- Timplsymtable=object(Tglobalsymtable)
- unitid:word;
- function varsymprefix:string;virtual;
- end;
- Tabstractrecordsymtable=object(Tcontainingsymtable)
- procedure insert(sym:Psym);virtual;
- function varsymtodata(sym:Psym;len:longint):longint;virtual;
- end;
- Precordsymtable=^Trecordsymtable;
- Trecordsymtable=object(Tabstractsymtable)
- end;
- Tobjectsymtable=object(Tabstractrecordsymtable)
- defowner:Pobjectsymtable;
- function speedsearch(const s:stringid;
- speedvalue:longint):Psym;virtual;
- end;
- Tprocsymtable=object(Tcontainingsymtable)
- {Replaces the old local and paramsymtables.}
- lexlevel:byte;
- paramdatasize:longint;
- {If this is a method, this points to the objectdef. It is
- possible to make another Tmethodsymtable and move this field
- to it, but I think the advantage is not worth it. (DM)}
- method:Pdef;
- procedure insert(sym:Psym);virtual;
- function speedsearch(const s:stringid;
- speedvalue:longint):Psym;virtual;
- function varsymtodata(sym:Psym;len:longint):longint;virtual;
- end;
- Tunitsymtable=object(Tcontainingsymtable)
- unittypecount:word;
- unitsym:Psym;
- constructor init(const n:string);
- {Checks if all used units are used.}
- procedure check_units;
- function speedsearch(const s:stringid;
- speedvalue:longint):Psym;virtual;
- function tconstsymtodata(sym:Psym;len:longint):longint;virtual;
- function varsymprefix:string;virtual;
- destructor done;virtual;
- end;
- Twithsymtable=object(Tsymtable)
- link:Pcontainingsymtable;
- constructor init(Alink:Pcontainingsymtable);
- function speedsearch(const s:stringid;
- speedvalue:longint):Psym;virtual;
- end;
- implementation
- uses symbols,files,globals,aasm,systems,defs,verbose;
- function data_align(length:longint):longint;
- begin
- if length>2 then
- data_align:=4
- else if length>1 then
- data_align:=2
- else
- data_align:=1;
- end;
- {****************************************************************************
- Tglobalsymtable
- ****************************************************************************}
- constructor Tglobalsymtable.init;
- begin
- inherited init;
- index_growsize:=128;
- end;
- procedure Tglobalsymtable.check_units;
- begin
- end;
- function Tglobalsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
- var ali:longint;
- segment:Paasmoutput;
- begin
- if Ptypedconstsym(sym)^.is_really_const then
- segment:=consts
- else
- segment:=datasegment;
- if (cs_smartlink in aktmoduleswitches) then
- segment^.concat(new(Pai_cut,init));
- ali:=data_align(len);
- align(datasize,ali);
- {$ifdef GDB}
- if cs_debuginfo in aktmoduleswitches then
- concatstabto(segment);
- {$endif GDB}
- segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname)));
- end;
- function Tglobalsymtable.varsymtodata(sym:Psym;len:longint):longint;
- var ali:longint;
- begin
- if (cs_smartlink in aktmoduleswitches) then
- bsssegment^.concat(new(Pai_cut,init));
- ali:=data_align(len);
- align(datasize,ali);
- {$ifdef GDB}
- if cs_debuginfo in aktmoduleswitches then
- concatstabto(bsssegment);
- {$endif GDB}
- bsssegment^.concat(new(Pai_datablock,
- init_global(sym^.mangledname,len)));
- varsymtodata:=inherited varsymtodata(sym,len);
- {This symbol can't be loaded to a register.}
- exclude(Pvarsym(sym)^.properties,vo_regable);
- end;
- {****************************************************************************
- Timplsymtable
- ****************************************************************************}
- function Timplsymtable.varsymprefix:string;
- begin
- varsymprefix:='U_'+name^+'_';
- end;
- {****************************************************************************
- Tinterfacesymtable
- ****************************************************************************}
- function Tinterfacesymtable.varsymprefix:string;
- begin
- varsymprefix:='_'+name^+'$$$'+'_';
- end;
- {****************************************************************************
- Tabstractrecordsymtable
- ****************************************************************************}
- procedure Tabstractrecordsymtable.insert(sym:Psym);
- begin
- { if typeof(sym)=typeof(Tenumsym) then
- if owner<>nil then
- owner^.insert(sym)
- else
- internalerror($990802)
- else}
- inherited insert(sym);
- end;
- function Tabstractrecordsymtable.varsymtodata(sym:Psym;
- len:longint):longint;
- begin
- datasize:=(datasize+(aktpackrecords-1)) and (not aktpackrecords-1);
- varsymtodata:=inherited varsymtodata(sym,len);
- end;
- {****************************************************************************
- Trecordsymtable
- ****************************************************************************}
- {****************************************************************************
- Tobjectsymtable
- ****************************************************************************}
- function Tobjectsymtable.speedsearch(const s:stringid;
- speedvalue:longint):Psym;
- var r:Psym;
- begin
- r:=inherited speedsearch(s,speedvalue);
- if (r<>nil) and (sp_static in Pprocdef(r)^.objprop) and
- allow_only_static then
- begin
- message(sym_e_only_static_in_static);
- speedsearch:=nil;
- end
- else
- speedsearch:=r;
- end;
- {****************************************************************************
- Tprocsymsymtable
- ****************************************************************************}
- procedure Tprocsymtable.insert(sym:Psym);
- begin
- { if (method<>nil) and (method^.search(sym^.name)<>nil) then}
- inherited insert(sym)
- { else
- duplicatesym(sym)};
- end;
- function Tprocsymtable.speedsearch(const s:stringid;
- speedvalue:longint):Psym;
- begin
- speedsearch:=inherited speedsearch(s,speedvalue);
- end;
- function Tprocsymtable.varsymtodata(sym:Psym;
- len:longint):longint;
- var modulo:longint;
- begin
- if typeof(sym^)=typeof(Tparamsym) then
- begin
- varsymtodata:=paramdatasize;
- paramdatasize:=align(datasize+len,target_os.stackalignment);
- end
- else
- begin
- {Sym must be a varsym.}
- {Align datastructures >=4 on a dword.}
- if len>=4 then
- align(len,4)
- else
- {$ifdef m68k}
- {Align datastructures with size 1,2,3 on a word.}
- align(len,2);
- {$else}
- {Align datastructures with size 2 or 3 on a word.}
- if len>=2 then
- align(len,2);
- {$endif}
- varsymtodata:=inherited varsymtodata(sym,len);
- end;
- end;
- {****************************************************************************
- Tunitsymtable
- ****************************************************************************}
- constructor Tunitsymtable.init(const n:string);
- begin
- inherited init;
- name:=stringdup(n);
- index_growsize:=128;
- end;
- procedure Tunitsymtable.check_units;
- begin
- end;
- function Tunitsymtable.speedsearch(const s:stringid;
- speedvalue:longint):Psym;
- var r:Psym;
- begin
- r:=inherited speedsearch(s,speedvalue);
- { if unitsym<>nil then
- Punitsym(unitsym)^.refs;}
- { if (r^.typ=unitsym) and assigned(current_module) and
- (current_module^.interfacesymtable<>@self) then
- r:=nil;}
- speedsearch:=r;
- end;
- function Tunitsymtable.tconstsymtodata(sym:Psym;len:longint):longint;
- var ali:longint;
- segment:Paasmoutput;
- begin
- if Ptypedconstsym(sym)^.is_really_const then
- segment:=consts
- else
- segment:=datasegment;
- if (cs_smartlink in aktmoduleswitches) then
- segment^.concat(new(Pai_cut,init));
- ali:=data_align(len);
- align(datasize,ali);
- {$ifdef GDB}
- if cs_debuginfo in aktmoduleswitches then
- concatstabto(segment);
- {$endif GDB}
- if (cs_smartlink in aktmoduleswitches) then
- segment^.concat(new(Pai_symbol,initname_global(sym^.mangledname)))
- else
- segment^.concat(new(Pai_symbol,initname(sym^.mangledname)));
- end;
- function Tunitsymtable.varsymprefix:string;
- begin
- varsymprefix:='U_'+name^+'_';
- end;
- destructor Tunitsymtable.done;
- begin
- stringdispose(name);
- inherited done;
- end;
- {****************************************************************************
- Twithsymtable
- ****************************************************************************}
- constructor Twithsymtable.init(Alink:Pcontainingsymtable);
- begin
- inherited init;
- link:=Alink;
- end;
- function Twithsymtable.speedsearch(const s:stringid;speedvalue:longint):Psym;
- begin
- speedsearch:=link^.speedsearch(s,speedvalue);
- end;
- end.
|