123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457 |
- {
- $Id$
- Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
- Symbol table implementation for the defenitions
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- {*************************************************************************************************************************
- TDEF (base class for defenitions)
- ****************************************************************************}
- constructor tdef.init;
- begin
- deftype:=abstractdef;
- owner := nil;
- next := nil;
- number := 0;
- if registerdef then
- symtablestack^.registerdef(@self);
- has_rtti:=false;
- {$ifdef GDB}
- is_def_stab_written := false;
- globalnb := 0;
- if assigned(lastglobaldef) then
- begin
- lastglobaldef^.nextglobal := @self;
- previousglobal:=lastglobaldef;
- end
- else
- begin
- firstglobaldef := @self;
- previousglobal := nil;
- end;
- lastglobaldef := @self;
- nextglobal := nil;
- sym := nil;
- {$endif GDB}
- end;
- constructor tdef.load;
- begin
- {$ifdef GDB}
- deftype:=abstractdef;
- is_def_stab_written := false;
- number := 0;
- sym := nil;
- owner := nil;
- next := nil;
- has_rtti:=false;
- globalnb := 0;
- if assigned(lastglobaldef) then
- begin
- lastglobaldef^.nextglobal := @self;
- previousglobal:=lastglobaldef;
- end
- else
- begin
- firstglobaldef := @self;
- previousglobal:=nil;
- end;
- lastglobaldef := @self;
- nextglobal := nil;
- {$endif GDB}
- end;
- destructor tdef.done;
- begin
- {$ifdef GDB}
- { first element ? }
- if not(assigned(previousglobal)) then
- begin
- firstglobaldef := nextglobal;
- firstglobaldef^.previousglobal:=nil;
- end
- else
- begin
- { remove reference in the element before }
- previousglobal^.nextglobal:=nextglobal;
- end;
- { last element ? }
- if not(assigned(nextglobal)) then
- begin
- lastglobaldef := previousglobal;
- if assigned(lastglobaldef) then
- lastglobaldef^.nextglobal:=nil;
- end
- else
- nextglobal^.previousglobal:=previousglobal;
- previousglobal:=nil;
- nextglobal:=nil;
- {$endif GDB}
- end;
- procedure tdef.write;
- begin
- {$ifdef GDB}
- if globalnb = 0 then
- begin
- if assigned(owner) then
- globalnb := owner^.getnewtypecount
- else
- begin
- globalnb := PGlobalTypeCount^;
- Inc(PGlobalTypeCount^);
- end;
- end;
- {$endif GDB}
- end;
- function tdef.size : longint;
- begin
- size:=savesize;
- end;
- {$ifdef GDB}
- procedure tdef.set_globalnb;
- begin
- globalnb :=PGlobalTypeCount^;
- inc(PglobalTypeCount^);
- end;
- function tdef.stabstring : pchar;
- begin
- stabstring := strpnew('t'+numberstring+';');
- end;
- function tdef.numberstring : string;
- var table : psymtable;
- begin
- {formal def have no type !}
- if deftype = formaldef then
- begin
- numberstring := voiddef^.numberstring;
- exit;
- end;
- if (not assigned(sym)) or (not sym^.isusedinstab) then
- begin
- {set even if debuglist is not defined}
- if assigned(sym) then
- sym^.isusedinstab := true;
- if assigned(debuglist) and not is_def_stab_written then
- concatstabto(debuglist);
- end;
- if not use_dbx then
- begin
- if globalnb = 0 then
- set_globalnb;
- numberstring := tostr(globalnb);
- end
- else
- begin
- if globalnb = 0 then
- begin
- if assigned(owner) then
- globalnb := owner^.getnewtypecount
- else
- begin
- globalnb := PGlobalTypeCount^;
- Inc(PGlobalTypeCount^);
- end;
- end;
- if assigned(sym) then
- begin
- table := sym^.owner;
- if table^.unitid > 0 then
- numberstring := '('+tostr(table^.unitid)+','
- +tostr(sym^.definition^.globalnb)+')'
- else
- numberstring := tostr(globalnb);
- exit;
- end;
- numberstring := tostr(globalnb);
- end;
- end;
- function tdef.allstabstring : pchar;
- var stabchar : string[2];
- ss,st : pchar;
- name : string;
- sym_line_no : longint;
- begin
- ss := stabstring;
- getmem(st,strlen(ss)+512);
- stabchar := 't';
- if deftype in tagtypes then
- stabchar := 'Tt';
- if assigned(sym) then
- begin
- name := sym^.name;
- sym_line_no:=sym^.line_no;
- end
- else
- begin
- name := ' ';
- sym_line_no:=0;
- end;
- strpcopy(st,'"'+name+':'+stabchar+numberstring+'=');
- strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
- allstabstring := strnew(st);
- freemem(st,strlen(ss)+512);
- strdispose(ss);
- end;
- procedure tdef.concatstabto(asmlist : paasmoutput);
- var stab_str : pchar;
- begin
- if ((sym = nil) or sym^.isusedinstab or use_dbx)
- and not is_def_stab_written then
- begin
- If use_dbx then
- begin
- { otherwise you get two of each def }
- If assigned(sym) then
- begin
- if sym^.typ=typesym then
- sym^.isusedinstab:=true;
- if (sym^.owner = nil) or
- ((sym^.owner^.symtabletype = unitsymtable) and
- punitsymtable(sym^.owner)^.dbx_count_ok) then
- begin
- {with DBX we get the definition from the other objects }
- is_def_stab_written := true;
- exit;
- end;
- end;
- end;
- { to avoid infinite loops }
- is_def_stab_written := true;
- stab_str := allstabstring;
- if asmlist = debuglist then do_count_dbx := true;
- { count_dbx(stab_str); moved to GDB.PAS}
- asmlist^.concat(new(pai_stabs,init(stab_str)));
- end;
- end;
- {$endif GDB}
- procedure tdef.deref;
- begin
- end;
- function tdef.needs_rtti : boolean;
- begin
- needs_rtti:=false;
- end;
- procedure tdef.generate_rtti;
- begin
- getlabel(rtti_label);
- rttilist^.concat(new(pai_label,init(rtti_label)));
- end;
- function tdef.get_rtti_label : plabel;
- begin
- if not(has_rtti) then
- generate_rtti;
- { I don't know what's the use of rtti_label
- but this was missing (PM) }
- get_rtti_label:=rtti_label;
- end;
- {*************************************************************************************************************************
- TSTRINGDEF
- ****************************************************************************}
- constructor tstringdef.init(l : byte);
- begin
- tdef.init;
- string_typ:=shortstring;
- deftype:=stringdef;
- len:=l;
- savesize:=len+1;
- end;
- constructor tstringdef.load;
- begin
- tdef.load;
- string_typ:=shortstring;
- deftype:=stringdef;
- len:=readbyte;
- savesize:=len+1;
- end;
- constructor tstringdef.longinit(l : longint);
- begin
- tdef.init;
- string_typ:=longstring;
- deftype:=stringdef;
- len:=l;
- savesize:=Sizeof(pointer);
- end;
- constructor tstringdef.longload;
- begin
- tdef.load;
- deftype:=stringdef;
- string_typ:=longstring;
- len:=readlong;
- savesize:=Sizeof(pointer);
- end;
- constructor tstringdef.ansiinit(l : longint);
- begin
- tdef.init;
- string_typ:=ansistring;
- deftype:=stringdef;
- len:=l;
- savesize:=sizeof(pointer);
- end;
- constructor tstringdef.ansiload;
- begin
- tdef.load;
- deftype:=stringdef;
- string_typ:=ansistring;
- len:=readlong;
- savesize:=sizeof(pointer);
- end;
- constructor tstringdef.wideinit(l : longint);
- begin
- tdef.init;
- string_typ:=widestring;
- deftype:=stringdef;
- len:=l;
- savesize:=sizeof(pointer);
- end;
- constructor tstringdef.wideload;
- begin
- tdef.load;
- deftype:=stringdef;
- string_typ:=ansistring;
- len:=readlong;
- savesize:=sizeof(pointer);
- end;
- function tstringdef.size : longint;
- begin
- size:=savesize;
- end;
- procedure tstringdef.write;
- begin
- {$ifndef NEWPPU}
- case string_typ of
- shortstring:
- writebyte(ibstringdef);
- longstring:
- writebyte(iblongstringdef);
- ansistring:
- writebyte(ibansistringdef);
- widestring:
- writebyte(ibwidestringdef);
- end;
- {$endif}
- tdef.write;
- if string_typ=shortstring then
- writebyte(len)
- else
- writelong(len);
- {$ifdef NEWPPU}
- case string_typ of
- shortstring : ppufile^.writeentry(ibstringdef);
- longstring : ppufile^.writeentry(iblongstringdef);
- ansistring : ppufile^.writeentry(ibansistringdef);
- widestring : ppufile^.writeentry(ibwidestringdef);
- end;
- {$endif}
- end;
- {$ifdef GDB}
- function tstringdef.stabstring : pchar;
- var
- bytest,charst,longst : string;
- begin
- case string_typ of
- shortstring : begin
- charst := typeglobalnumber('char');
- { this is what I found in stabs.texinfo but
- gdb 4.12 for go32 doesn't understand that !! }
- {$IfDef GDBknowsstrings}
- stabstring := strpnew('n'+charst+';'+tostr(len));
- {$else}
- bytest := typeglobalnumber('byte');
- stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
- +',0,8;st:ar'+bytest
- +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
- {$EndIf}
- end;
- longstring : begin
- charst := typeglobalnumber('char');
- { this is what I found in stabs.texinfo but
- gdb 4.12 for go32 doesn't understand that !! }
- {$IfDef GDBknowsstrings}
- stabstring := strpnew('n'+charst+';'+tostr(len));
- {$else}
- bytest := typeglobalnumber('byte');
- longst := typeglobalnumber('longint');
- stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
- +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
- +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
- {$EndIf}
- end;
- ansistring : begin
- { an ansi string looks like a pchar easy !! }
- stabstring:=strpnew('*'+typeglobalnumber('char'));
- end;
- widestring : begin
- { an ansi string looks like a pchar easy !! }
- stabstring:=strpnew('*'+typeglobalnumber('char'));
- end;
- end;
- end;
- procedure tstringdef.concatstabto(asmlist : paasmoutput);
- begin
- inherited concatstabto(asmlist);
- end;
- {$endif GDB}
- function tstringdef.needs_rtti : boolean;
- begin
- needs_rtti:=string_typ in [ansistring,widestring];
- end;
- {*************************************************************************************************************************
- TENUMDEF
- ****************************************************************************}
- constructor tenumdef.init;
- begin
- tdef.init;
- deftype:=enumdef;
- max:=0;
- savesize:=Sizeof(longint);
- has_jumps:=false;
- {$ifdef GDB}
- first := Nil;
- {$endif GDB}
- end;
- constructor tenumdef.load;
- begin
- tdef.load;
- deftype:=enumdef;
- max:=readlong;
- savesize:=Sizeof(longint);
- has_jumps:=false;
- first := Nil;
- end;
- destructor tenumdef.done;
- begin
- inherited done;
- end;
- procedure tenumdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibenumdef);
- {$endif}
- tdef.write;
- writelong(max);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibenumdef);
- {$endif}
- end;
- {$ifdef GDB}
- function tenumdef.stabstring : pchar;
- var st,st2 : pchar;
- p : penumsym;
- s : string;
- memsize : word;
- begin
- memsize := memsizeinc;
- getmem(st,memsize);
- strpcopy(st,'e');
- p := first;
- while assigned(p) do
- begin
- s :=p^.name+':'+tostr(p^.value)+',';
- { place for the ending ';' also }
- if (strlen(st)+length(s)+1<memsize) then
- strpcopy(strend(st),s)
- else
- begin
- getmem(st2,memsize+memsizeinc);
- strcopy(st2,st);
- freemem(st,memsize);
- st := st2;
- memsize := memsize+memsizeinc;
- strpcopy(strend(st),s);
- end;
- p := p^.next;
- end;
- strpcopy(strend(st),';');
- stabstring := strnew(st);
- freemem(st,memsize);
- end;
- {$endif GDB}
- {*************************************************************************************************************************
- TORDDEF
- ****************************************************************************}
- constructor torddef.init(t : tbasetype;v,b : longint);
- begin
- tdef.init;
- deftype:=orddef;
- low:=v;
- high:=b;
- typ:=t;
- setsize;
- end;
- constructor torddef.load;
- begin
- tdef.load;
- deftype:=orddef;
- typ:=tbasetype(readbyte);
- low:=readlong;
- high:=readlong;
- rangenr:=0;
- setsize;
- end;
- procedure torddef.setsize;
- begin
- if typ=uauto then
- begin
- { generate a unsigned range if high<0 and low>=0 }
- if (low>=0) and (high<0) then
- begin
- savesize:=4;
- typ:=u32bit;
- end
- else if (low>=0) and (high<=255) then
- begin
- savesize:=1;
- typ:=u8bit;
- end
- else if (low>=-128) and (high<=127) then
- begin
- savesize:=1;
- typ:=s8bit;
- end
- else if (low>=0) and (high<=65536) then
- begin
- savesize:=2;
- typ:=u16bit;
- end
- else if (low>=-32768) and (high<=32767) then
- begin
- savesize:=2;
- typ:=s16bit;
- end
- else
- begin
- savesize:=4;
- typ:=s32bit;
- end;
- end
- else
- begin
- case typ of
- u8bit,s8bit,
- uchar,bool8bit : savesize:=1;
- u16bit,s16bit,
- bool16bit : savesize:=2;
- s32bit,u32bit,
- bool32bit : savesize:=4;
- else
- savesize:=0;
- end;
- end;
- { there are no entrys for range checking }
- rangenr:=0;
- end;
- procedure torddef.genrangecheck;
- begin
- if rangenr=0 then
- begin
- { generate two constant for bounds }
- getlabelnr(rangenr);
- if (cs_smartlink in aktswitches) then
- datasegment^.concat(new(pai_symbol,init_global('R_'+current_module^.mainsource^+tostr(rangenr))))
- else
- datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr))));
- if low<=high then
- begin
- datasegment^.concat(new(pai_const,init_32bit(low)));
- datasegment^.concat(new(pai_const,init_32bit(high)));
- end
- { for u32bit we need two bounds }
- else
- begin
- datasegment^.concat(new(pai_const,init_32bit(low)));
- datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
- inc(nextlabelnr);
- if (cs_smartlink in aktswitches) then
- datasegment^.concat(new(pai_symbol,init_global('R_'+current_module^.mainsource^+tostr(rangenr+1))))
- else
- datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr+1))));
- datasegment^.concat(new(pai_const,init_32bit($80000000)));
- datasegment^.concat(new(pai_const,init_32bit(high)));
- end;
- end;
- end;
- procedure torddef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(iborddef);
- {$endif}
- tdef.write;
- writebyte(byte(typ));
- writelong(low);
- writelong(high);
- {$ifdef NEWPPU}
- ppufile^.writeentry(iborddef);
- {$endif}
- end;
- {$ifdef GDB}
- function torddef.stabstring : pchar;
- begin
- case typ of
- uvoid : stabstring := strpnew(numberstring+';');
- {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
- bool8bit,
- bool16bit,
- bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
- { u32bit : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';0;-1;'); }
- else
- stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
- end;
- end;
- {$endif GDB}
- {*************************************************************************************************************************
- TFLOATDEF
- ****************************************************************************}
- constructor tfloatdef.init(t : tfloattype);
- begin
- tdef.init;
- deftype:=floatdef;
- typ:=t;
- setsize;
- end;
- constructor tfloatdef.load;
- begin
- tdef.load;
- deftype:=floatdef;
- typ:=tfloattype(readbyte);
- setsize;
- end;
- procedure tfloatdef.setsize;
- begin
- case typ of
- f16bit:
- savesize:=2;
- f32bit,s32real:
- savesize:=4;
- s64real:
- savesize:=8;
- s64bit:
- savesize:=8;
- s80real:
- savesize:=extended_size;
- else savesize:=0;
- end;
- end;
- procedure tfloatdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibfloatdef);
- {$endif}
- tdef.write;
- writebyte(byte(typ));
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibfloatdef);
- {$endif}
- end;
- {$ifdef GDB}
- function tfloatdef.stabstring : pchar;
- begin
- case typ of
- s32real,
- s64real : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
- { for fixed real use longint instead to be able to }
- { debug something at least }
- f32bit:
- stabstring := s32bitdef^.stabstring;
- f16bit:
- stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
- tostr($ffff)+';');
- { found this solution in stabsread.c from GDB v4.16 }
- s64bit : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
- {$ifdef i386}
- { under dos at least you must give a size of twelve instead of 10 !! }
- { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
- s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
- {$endif i386}
- else
- internalerror(10005);
- end;
- end;
- {$endif GDB}
- {*************************************************************************************************************************
- TFILEDEF
- ****************************************************************************}
- constructor tfiledef.init(ft : tfiletype;tas : pdef);
- begin
- inherited init;
- deftype:=filedef;
- filetype:=ft;
- typed_as:=tas;
- setsize;
- end;
- constructor tfiledef.load;
- begin
- tdef.load;
- deftype:=filedef;
- filetype:=tfiletype(readbyte);
- if filetype=ft_typed then
- typed_as:=readdefref
- else
- typed_as:=nil;
- setsize;
- end;
- procedure tfiledef.deref;
- begin
- if filetype=ft_typed then
- resolvedef(typed_as);
- end;
- procedure tfiledef.setsize;
- begin
- {$ifdef i386}
- case target_info.target of
- target_LINUX:
- begin
- case filetype of
- ft_text : savesize:=432;
- ft_typed,ft_untyped : savesize:=304;
- end;
- end;
- target_Win32:
- begin
- case filetype of
- ft_text : savesize:=434;
- ft_typed,ft_untyped : savesize:=306;
- end;
- end
- else
- begin
- case filetype of
- ft_text : savesize:=256;
- ft_typed,ft_untyped : savesize:=128;
- end;
- end;
- end;
- {$endif}
- {$ifdef m68k}
- case filetype of
- ft_text : savesize:=256;
- ft_typed,
- ft_untyped : savesize:=128;
- end;
- {$endif}
- end;
- procedure tfiledef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibfiledef);
- {$endif}
- tdef.write;
- writebyte(byte(filetype));
- if filetype=ft_typed then
- writedefref(typed_as);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibfiledef);
- {$endif}
- end;
- {$ifdef GDB}
- function tfiledef.stabstring : pchar;
- var Handlebitsize,namesize : longint;
- Handledef :string;
- begin
- {$IfDef GDBknowsfiles}
- case filetyp of
- ft_typed : stabstring := strpnew('d'+typed_as^.numberstring{+';'});
- ft_untyped : stabstring := strpnew('d'+voiddef^.numberstring{+';'});
- ft_text : stabstring := strpnew('d'+cchardef^.numberstring{+';'});
- end;
- {$Else }
- {based on
- filerec = record
- handle : word;
- mode : word;
- recsize : word;
- _private : array[1..26] of byte;
- userdata : array[1..16] of byte;
- name : string[79 or 255 for linux]; }
- {$ifdef i386}
- if (target_info.target=target_GO32V1) or
- (target_info.target=target_GO32V2) then
- namesize:=79
- else
- namesize:=255;
- if (target_info.target=target_Win32) then
- begin
- Handledef:='longint';
- Handlebitsize:=32;
- end
- else
- begin
- Handledef:='word';
- HandleBitSize:=16;
- end;
- {$endif}
- {$ifdef m68k}
- namesize:=79;
- Handledef:='word';
- HandleBitSize:=16;
- {$endif}
- { the buffer part is still missing !! (PM) }
- { but the string could become too long !! }
- stabstring := strpnew('s'+tostr(savesize)+
- 'HANDLE:'+typeglobalnumber(Handledef)+',0,'+tostr(HandleBitSize)+';'+
- 'MODE:'+typeglobalnumber('word')+','+tostr(HandleBitSize)+',16;'+
- 'RECSIZE:'+typeglobalnumber('word')+','+tostr(HandleBitSize+16)+',16;'+
- '_PRIVATE:ar'+typeglobalnumber('word')+';1;26;'+typeglobalnumber('byte')
- +','+tostr(HandleBitSize+32)+',208;'+
- 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
- +','+tostr(HandleBitSize+240)+',128;'+
- { 'NAME:s'+tostr(namesize+1)+
- 'length:'+typeglobalnumber('byte')+',0,8;'+
- 'st:ar'+typeglobalnumber('word')+';1;'
- +tostr(namesize)+';'+typeglobalnumber('char')+',8,'+tostr(8*namesize)+';;'+}
- 'NAME:ar'+typeglobalnumber('word')+';0;'
- +tostr(namesize)+';'+typeglobalnumber('char')+
- ','+tostr(HandleBitSize+368)+','+tostr(8*(namesize+1))+';;');
- {$EndIf}
- end;
- procedure tfiledef.concatstabto(asmlist : paasmoutput);
- begin
- { most file defs are unnamed !!! }
- if ((sym = nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
- begin
- if assigned(typed_as) then forcestabto(asmlist,typed_as);
- inherited concatstabto(asmlist);
- end;
- end;
- {$endif GDB}
- {*************************************************************************************************************************
- TPOINTERDEF
- ****************************************************************************}
- constructor tpointerdef.init(def : pdef);
- begin
- inherited init;
- deftype:=pointerdef;
- definition:=def;
- savesize:=Sizeof(pointer);
- end;
- constructor tpointerdef.load;
- begin
- tdef.load;
- deftype:=pointerdef;
- { the real address in memory is calculated later (deref) }
- definition:=readdefref;
- savesize:=Sizeof(pointer);
- end;
- procedure tpointerdef.deref;
- begin
- resolvedef(definition);
- end;
- procedure tpointerdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibpointerdef);
- {$endif}
- tdef.write;
- writedefref(definition);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibpointerdef);
- {$endif}
- end;
- {$ifdef GDB}
- function tpointerdef.stabstring : pchar;
- begin
- stabstring := strpnew('*'+definition^.numberstring);
- end;
- procedure tpointerdef.concatstabto(asmlist : paasmoutput);
- var st,nb : string;
- sym_line_no : longint;
- begin
- if ( (sym=nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
- begin
- if assigned(definition) then
- if definition^.deftype in [recorddef,objectdef] then
- begin
- is_def_stab_written := true;
- {to avoid infinite recursion in record with next-like fields }
- nb := definition^.numberstring;
- is_def_stab_written := false;
- if not definition^.is_def_stab_written then
- begin
- if assigned(definition^.sym) then
- begin
- if assigned(sym) then
- begin
- st := sym^.name;
- sym_line_no:=sym^.line_no;
- end
- else
- begin
- st := ' ';
- sym_line_no:=0;
- end;
- st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
- +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
- if asmlist = debuglist then do_count_dbx := true;
- asmlist^.concat(new(pai_stabs,init(strpnew(st))));
- end;
- end else inherited concatstabto(asmlist);
- is_def_stab_written := true;
- end else
- begin
- forcestabto(asmlist,definition);
- inherited concatstabto(asmlist);
- end;
- end;
- end;
- {$endif GDB}
- {*************************************************************************************************************************
- TCLASSREFDEF
- ****************************************************************************}
- constructor tclassrefdef.init(def : pdef);
- begin
- inherited init(def);
- deftype:=classrefdef;
- definition:=def;
- savesize:=Sizeof(pointer);
- end;
- constructor tclassrefdef.load;
- begin
- inherited load;
- deftype:=classrefdef;
- end;
- procedure tclassrefdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibclassrefdef);
- {$endif}
- tdef.write;
- writedefref(definition);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibclassrefdef);
- {$endif}
- end;
- {$ifdef GDB}
- function tclassrefdef.stabstring : pchar;
- begin
- stabstring:=strpnew('');
- end;
- procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
- begin
- end;
- {$endif GDB}
- {***********************************************************************************
- TSETDEF
- ***************************************************************************}
- constructor tsetdef.init(s : pdef;high : longint);
- begin
- inherited init;
- deftype:=setdef;
- setof:=s;
- if high<32 then
- begin
- settype:=smallset;
- savesize:=Sizeof(longint);
- end
- else
- if high<256 then
- begin
- settype:=normset;
- savesize:=32;
- end
- else
- {$ifdef testvarsets}
- if high<$10000 then
- begin
- settype:=varset;
- savesize:=4*((high+31) div 32);
- end
- else
- {$endif testvarsets}
- Message(sym_e_ill_type_decl_set);
- end;
- constructor tsetdef.load;
- begin
- tdef.load;
- deftype:=setdef;
- setof:=readdefref;
- settype:=tsettype(readbyte);
- case settype of
- normset : savesize:=32;
- varset : savesize:=readlong;
- smallset : savesize:=Sizeof(longint);
- end;
- end;
- procedure tsetdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibsetdef);
- {$endif}
- tdef.write;
- writedefref(setof);
- writebyte(byte(settype));
- if settype=varset then
- writelong(savesize);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibsetdef);
- {$endif}
- end;
- {$ifdef GDB}
- function tsetdef.stabstring : pchar;
- begin
- stabstring := strpnew('S'+setof^.numberstring);
- end;
- procedure tsetdef.concatstabto(asmlist : paasmoutput);
- begin
- if ( not assigned(sym) or sym^.isusedinstab or use_dbx) and
- not is_def_stab_written then
- begin
- if assigned(setof) then
- forcestabto(asmlist,setof);
- inherited concatstabto(asmlist);
- end;
- end;
- {$endif GDB}
- procedure tsetdef.deref;
- begin
- resolvedef(setof);
- end;
- {***********************************************************************************
- TFORMALDEF
- ***************************************************************************}
- constructor tformaldef.init;
- begin
- inherited init;
- deftype:=formaldef;
- savesize:=Sizeof(pointer);
- end;
- constructor tformaldef.load;
- begin
- tdef.load;
- deftype:=formaldef;
- savesize:=Sizeof(pointer);
- end;
- procedure tformaldef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibformaldef);
- {$endif}
- tdef.write;
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibformaldef);
- {$endif}
- end;
- {$ifdef GDB}
- function tformaldef.stabstring : pchar;
- begin
- stabstring := strpnew('formal'+numberstring+';');
- end;
- procedure tformaldef.concatstabto(asmlist : paasmoutput);
- begin
- { formaldef can't be stab'ed !}
- end;
- {$endif GDB}
- {***********************************************************************************
- TARRAYDEF
- ***************************************************************************}
- constructor tarraydef.init(l,h : longint;rd : pdef);
- begin
- tdef.init;
- deftype:=arraydef;
- lowrange:=l;
- highrange:=h;
- rangedef:=rd;
- rangenr:=0;
- definition:=nil;
- end;
- constructor tarraydef.load;
- begin
- tdef.load;
- deftype:=arraydef;
- { the addresses are calculated later }
- definition:=readdefref;
- rangedef:=readdefref;
- lowrange:=readlong;
- highrange:=readlong;
- rangenr:=0;
- end;
- procedure tarraydef.genrangecheck;
- begin
- if rangenr=0 then
- begin
- { generates the data for range checking }
- getlabelnr(rangenr);
- datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr))));
- datasegment^.concat(new(pai_const,init_32bit(lowrange)));
- datasegment^.concat(new(pai_const,init_32bit(highrange)));
- end;
- end;
- procedure tarraydef.deref;
- begin
- resolvedef(definition);
- resolvedef(rangedef);
- end;
- procedure tarraydef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibarraydef);
- {$endif}
- tdef.write;
- writedefref(definition);
- writedefref(rangedef);
- writelong(lowrange);
- writelong(highrange);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibarraydef);
- {$endif}
- end;
- {$ifdef GDB}
- function tarraydef.stabstring : pchar;
- begin
- stabstring := strpnew('ar'+rangedef^.numberstring+';'
- +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
- end;
- procedure tarraydef.concatstabto(asmlist : paasmoutput);
- begin
- if (not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not is_def_stab_written then
- begin
- {when array are inserted they have no definition yet !!}
- if assigned(definition) then
- inherited concatstabto(asmlist);
- end;
- end;
- {$endif GDB}
- function tarraydef.elesize : longint;
- begin
- elesize:=definition^.size;
- end;
- function tarraydef.size : longint;
- begin
- size:=(highrange-lowrange+1)*elesize;
- end;
- function tarraydef.needs_rtti : boolean;
- begin
- needs_rtti:=definition^.needs_rtti;
- end;
- {***********************************************************************************
- TRECDEF
- ***************************************************************************}
- constructor trecdef.init(p : psymtable);
- begin
- tdef.init;
- deftype:=recorddef;
- symtable:=p;
- savesize:=symtable^.datasize;
- symtable^.defowner := @self;
- end;
- constructor trecdef.load;
- var
- oldread_member : boolean;
- begin
- tdef.load;
- deftype:=recorddef;
- savesize:=readlong;
- oldread_member:=read_member;
- read_member:=true;
- symtable:=new(psymtable,loadasstruct(recordsymtable));
- read_member:=oldread_member;
- symtable^.defowner := @self;
- end;
- destructor trecdef.done;
- begin
- if assigned(symtable) then dispose(symtable,done);
- inherited done;
- end;
- var
- brtti : boolean;
- procedure check_rec_rtti(s : psym);
- begin
- if (s^.typ=varsym) and (pvarsym(s)^.definition^.needs_rtti) then
- brtti:=true;
- end;
- function trecdef.needs_rtti : boolean;
- var
- oldb : boolean;
- begin
- { there are recursive calls to needs_rtti possible, }
- { so we have to change to old value how else should }
- { we do that ? check_rec_rtti can't be a nested }
- { procedure of needs_rtti ! }
- oldb:=brtti;
- brtti:=false;
- symtable^.foreach(check_rec_rtti);
- needs_rtti:=brtti;
- brtti:=oldb;
- end;
- procedure trecdef.deref;
- var
- hp : pdef;
- oldrecsyms : psymtable;
- begin
- oldrecsyms:=aktrecordsymtable;
- aktrecordsymtable:=symtable;
- { now dereference the definitions }
- hp:=symtable^.rootdef;
- while assigned(hp) do
- begin
- hp^.deref;
- { set owner }
- hp^.owner:=symtable;
- hp:=hp^.next;
- end;
- {$ifdef tp}
- symtable^.foreach(derefsym);
- {$else}
- symtable^.foreach(@derefsym);
- {$endif}
- aktrecordsymtable:=oldrecsyms;
- end;
- procedure trecdef.write;
- var
- oldread_member : boolean;
- begin
- oldread_member:=read_member;
- read_member:=true;
- {$ifndef NEWPPU}
- writebyte(ibrecorddef);
- {$endif}
- tdef.write;
- writelong(savesize);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibrecorddef);
- {$endif}
- self.symtable^.writeasstruct;
- read_member:=oldread_member;
- end;
- {$ifdef GDB}
- Const StabRecString : pchar = Nil;
- StabRecSize : longint = 0;
- RecOffset : Longint = 0;
- procedure addname(p : psym);
- var
- news, newrec : pchar;
- begin
- { static variables from objects are like global objects }
- if ((p^.properties and sp_static)<>0) then
- exit;
- If p^.typ = varsym then
- begin
- newrec := strpnew(p^.name+':'+pvarsym(p)^.definition^.numberstring
- +','+tostr(pvarsym(p)^.address*8)+','
- +tostr(pvarsym(p)^.definition^.size*8)+';');
- if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
- begin
- getmem(news,stabrecsize+memsizeinc);
- strcopy(news,stabrecstring);
- freemem(stabrecstring,stabrecsize);
- stabrecsize:=stabrecsize+memsizeinc;
- stabrecstring:=news;
- end;
- strcat(StabRecstring,newrec);
- strdispose(newrec);
- {This should be used for case !!}
- RecOffset := RecOffset + pvarsym(p)^.definition^.size;
- end;
- end;
- function trecdef.stabstring : pchar;
- Var oldrec : pchar;
- oldsize : longint;
- begin
- oldrec := stabrecstring;
- oldsize:=stabrecsize;
- GetMem(stabrecstring,memsizeinc);
- stabrecsize:=memsizeinc;
- strpcopy(stabRecString,'s'+tostr(savesize));
- RecOffset := 0;
- {$ifdef tp}
- symtable^.foreach(addname);
- {$else}
- symtable^.foreach(@addname);
- {$endif}
- { FPC doesn't want to convert a char to a pchar}
- { is this a bug ? }
- strpcopy(strend(StabRecString),';');
- stabstring := strnew(StabRecString);
- Freemem(stabrecstring,stabrecsize);
- stabrecstring := oldrec;
- stabrecsize:=oldsize;
- end;
- procedure trecdef.concatstabto(asmlist : paasmoutput);
- begin
- if (not assigned(sym) or sym^.isusedinstab or use_dbx) and
- (not is_def_stab_written) then
- inherited concatstabto(asmlist);
- end;
- {$endif GDB}
- {***********************************************************************************
- TABSTRACTPROCDEF
- ***************************************************************************}
- constructor tabstractprocdef.init;
- begin
- inherited init;
- para1:=nil;
- {$ifdef StoreFPULevel}
- fpu_used:=255;
- {$endif StoreFPULevel}
- options:=0;
- retdef:=voiddef;
- savesize:=Sizeof(pointer);
- end;
- destructor tabstractprocdef.done;
- var
- hp : pdefcoll;
- begin
- hp:=para1;
- while assigned(hp) do
- begin
- para1:=hp^.next;
- dispose(hp);
- hp:=para1;
- end;
- inherited done;
- end;
- procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
- var
- hp : pdefcoll;
- begin
- new(hp);
- hp^.paratyp:=vsp;
- hp^.data:=p;
- hp^.next:=para1;
- para1:=hp;
- end;
- procedure tabstractprocdef.deref;
- var
- hp : pdefcoll;
- begin
- inherited deref;
- resolvedef(retdef);
- hp:=para1;
- while assigned(hp) do
- begin
- resolvedef(hp^.data);
- hp:=hp^.next;
- end;
- end;
- constructor tabstractprocdef.load;
- var
- last,hp : pdefcoll;
- count,i : word;
- begin
- tdef.load;
- retdef:=readdefref;
- {$ifdef StoreFPULevel}
- fpu_used:=readbyte;
- {$endif StoreFPULevel}
- options:=readlong;
- count:=readword;
- para1:=nil;
- savesize:=Sizeof(pointer);
- for i:=1 to count do
- begin
- new(hp);
- hp^.paratyp:=tvarspez(readbyte);
- hp^.data:=readdefref;
- hp^.next:=nil;
- if para1=nil then
- para1:=hp
- else
- last^.next:=hp;
- last:=hp;
- end;
- end;
- function tabstractprocdef.para_size : longint;
- var
- pdc : pdefcoll;
- l : longint;
- begin
- l:=0;
- pdc:=para1;
- while assigned(pdc) do
- begin
- case pdc^.paratyp of
- vs_value : l:=l+pdc^.data^.size+(pdc^.data^.size mod 2);
- vs_var : l:=l+sizeof(pointer);
- vs_const : if dont_copy_const_param(pdc^.data) then
- l:=l+sizeof(pointer)
- else
- l:=l+pdc^.data^.size+(pdc^.data^.size mod 2);
- end;
- pdc:=pdc^.next;
- end;
- para_size:=l;
- end;
- procedure tabstractprocdef.write;
- var
- count : word;
- hp : pdefcoll;
- begin
- tdef.write;
- writedefref(retdef);
- {$ifdef StoreFPULevel}
- writebyte(FPU_used);
- {$endif StoreFPULevel}
- writelong(options);
- hp:=para1;
- count:=0;
- while assigned(hp) do
- begin
- inc(count);
- hp:=hp^.next;
- end;
- writeword(count);
- hp:=para1;
- while assigned(hp) do
- begin
- writebyte(byte(hp^.paratyp));
- writedefref(hp^.data);
- hp:=hp^.next;
- end;
- end;
- function tabstractprocdef.demangled_paras : string;
- var s : string;
- p : pdefcoll;
- begin
- s:='';
- p:=para1;
- if assigned(p) then
- begin
- s:=s+'(';
- while assigned(p) do
- begin
- if assigned(p^.data^.sym) then
- s:=s+p^.data^.sym^.name
- else if p^.paratyp=vs_var then
- s:=s+'var'
- else if p^.paratyp=vs_const then
- s:=s+'const';
- p:=p^.next;
- if assigned(p) then
- s:=s+','
- else
- s:=s+')';
- end;
- end;
- demangled_paras:=s;
- end;
- {$ifdef GDB}
- function tabstractprocdef.stabstring : pchar;
- begin
- stabstring := strpnew('abstractproc'+numberstring+';');
- end;
- procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
- begin
- if (not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not is_def_stab_written then
- begin
- if assigned(retdef) then forcestabto(asmlist,retdef);
- inherited concatstabto(asmlist);
- end;
- end;
- {$endif GDB}
- {***********************************************************************************
- TPROCDEF
- ***************************************************************************}
- constructor tprocdef.init;
- begin
- inherited init;
- deftype:=procdef;
- _mangledname:=nil;
- nextoverloaded:=nil;
- extnumber:=-1;
- localst:=new(psymtable,init(localsymtable));
- parast:=new(psymtable,init(parasymtable));
- { this is used by insert
- to check same names in parast and localst }
- localst^.next:=parast;
- {$ifdef UseBrowser}
- defref:=nil;
- if make_ref then
- add_new_ref(defref,@tokenpos);
- lastref:=defref;
- lastwritten:=nil;
- refcount:=1;
- {$endif UseBrowser}
- { first, we assume, that all registers are used }
- {$ifdef i386}
- usedregisters:=$ff;
- {$endif i386}
- {$ifdef m68k}
- usedregisters:=$FFFF;
- {$endif}
- {$ifdef alpha}
- usedregisters_int:=$ffffffff;
- usedregisters_fpu:=$ffffffff;
- {$endif alpha}
- forwarddef:=true;
- _class := nil;
- end;
- constructor tprocdef.load;
- var
- s : string;
- begin
- { deftype:=procdef; this is at the wrong place !! }
- inherited load;
- deftype:=procdef;
- {$ifdef i386}
- usedregisters:=readbyte;
- {$endif i386}
- {$ifdef m68k}
- usedregisters:=readword;
- {$endif}
- {$ifdef alpha}
- usedregisters_int:=readlong;
- usedregisters_fpu:=readlong;
- {$endif alpha}
- s:=readstring;
- setstring(_mangledname,s);
- extnumber:=readlong;
- nextoverloaded:=pprocdef(readdefref);
- _class := pobjectdef(readdefref);
- if gendeffile and ((options and poexports)<>0) then
- deffile.AddExport(mangledname);
- parast:=nil;
- localst:=nil;
- forwarddef:=false;
- {$ifdef UseBrowser}
- if (current_module^.flags and uf_uses_browser)<>0 then
- load_references
- else
- begin
- lastref:=nil;
- lastwritten:=nil;
- defref:=nil;
- refcount:=0;
- end;
- {$endif UseBrowser}
- end;
- {$ifdef UseBrowser}
- procedure tprocdef.load_references;
- var fileindex : word;
- b : byte;
- l,c : longint;
- begin
- b:=readbyte;
- refcount:=0;
- lastref:=nil;
- lastwritten:=nil;
- defref:=nil;
- while b=ibref do
- begin
- fileindex:=readword;
- l:=readlong;
- c:=readword;
- inc(refcount);
- lastref:=new(pref,load(lastref,fileindex,l,c));
- if refcount=1 then defref:=lastref;
- b:=readbyte;
- end;
- if b <> ibend then
- { Message(unit_f_ppu_read);
- message disappeared ?? }
- Comment(V_fatal,'error in load_reference');
- end;
- procedure tprocdef.write_references;
- var ref : pref;
- begin
- { references do not change the ppu caracteristics }
- { this only save the references to variables/functions }
- { defined in the unit what about the others }
- ppufile^.do_crc:=false;
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- writebyte(ibref);
- writeword(ref^.posinfo.fileindex);
- writelong(ref^.posinfo.line);
- writeword(ref^.posinfo.column);
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- ppufile^.do_crc:=true;
- end;
- procedure tprocdef.write_external_references;
- var ref : pref;
- begin
- ppufile^.do_crc:=false;
- if lastwritten=lastref then exit;
- writebyte(ibextdefref);
- writedefref(@self);
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- writebyte(ibref);
- writeword(ref^.posinfo.fileindex);
- writelong(ref^.posinfo.line);
- writeword(ref^.posinfo.column);
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- ppufile^.do_crc:=true;
- end;
- procedure tprocdef.write_ref_to_file(var f : text);
- var ref : pref;
- i : longint;
- begin
- ref:=defref;
- if assigned(ref) then
- begin
- for i:=1 to reffile_indent do
- system.write(f,' ');
- writeln(f,'***',mangledname);
- end;
- inc(reffile_indent,2);
- while assigned(ref) do
- begin
- for i:=1 to reffile_indent do
- system.write(f,' ');
- writeln(f,ref^.get_file_line);
- ref:=ref^.nextref;
- end;
- dec(reffile_indent,2);
- end;
- {$endif UseBrowser}
- destructor tprocdef.done;
- begin
- if assigned(parast) then
- dispose(parast,done);
- if assigned(localst) then
- dispose(localst,done);
- if
- {$ifdef tp}
- not(use_big) and
- {$endif}
- assigned(_mangledname) then
- strdispose(_mangledname);
- inherited done;
- end;
- procedure tprocdef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibprocdef);
- {$endif}
- inherited write;
- {$ifdef i386}
- writebyte(usedregisters);
- {$endif i386}
- {$ifdef m68k}
- writeword(usedregisters);
- {$endif}
- {$ifdef alpha}
- writelong(usedregisters_int);
- writelong(usedregisters_fpu);
- {$endif alpha}
- writestring(mangledname);
- writelong(extnumber);
- writedefref(nextoverloaded);
- writedefref(_class);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibprocdef);
- {$endif}
- {$ifdef UseBrowser}
- if (current_module^.flags and uf_uses_browser)<>0 then
- write_references;
- {$endif UseBrowser}
- end;
- {$ifdef GDB}
- procedure addparaname(p : psym);
- var vs : char;
- begin
- if pvarsym(p)^.varspez = vs_value then vs := '1'
- else vs := '0';
- strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.definition^.numberstring+','+vs+';');
- end;
- function tprocdef.stabstring : pchar;
- var param : pdefcoll;
- i : word;
- vartyp : char;
- oldrec : pchar;
- begin
- oldrec := stabrecstring;
- getmem(StabRecString,1024);
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- param := param^.next;
- end;
- strpcopy(StabRecString,'f'+retdef^.numberstring);
- if i>0 then
- begin
- strpcopy(strend(StabRecString),','+tostr(i)+';');
- if assigned(parast) then
- {$IfDef TP}
- parast^.foreach(addparaname)
- {$Else}
- parast^.foreach(@addparaname)
- {$EndIf}
- else
- begin
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
- {Here we have lost the parameter names !!}
- {using lower case parameters }
- strpcopy(strend(stabrecstring),'p'+tostr(i)
- +':'+param^.data^.numberstring+','+vartyp+';');
- param := param^.next;
- end;
- end;
- {strpcopy(strend(StabRecString),';');}
- end;
- stabstring := strnew(stabrecstring);
- freemem(stabrecstring,1024);
- stabrecstring := oldrec;
- end;
- procedure tprocdef.concatstabto(asmlist : paasmoutput);
- begin
- end;
- {$endif GDB}
- procedure tprocdef.deref;
- begin
- inherited deref;
- resolvedef(pdef(nextoverloaded));
- resolvedef(pdef(_class));
- end;
- function tprocdef.mangledname : string;
- {$ifdef tp}
- var
- oldpos : longint;
- s : string;
- b : byte;
- {$endif tp}
- begin
- {$ifdef tp}
- if use_big then
- begin
- symbolstream.seek(longint(_mangledname));
- symbolstream.read(b,1);
- symbolstream.read(s[1],b);
- s[0]:=chr(b);
- mangledname:=s;
- end
- else
- {$endif}
- mangledname:=strpas(_mangledname);
- end;
- {$IfDef GDB}
- function tprocdef.cplusplusmangledname : string;
- var
- s,s2 : string;
- param : pdefcoll;
- begin
- s := sym^.name;
- if _class <> nil then
- begin
- s2 := _class^.name^;
- s := s+'__'+tostr(length(s2))+s2;
- end else s := s + '_';
- param := para1;
- while assigned(param) do
- begin
- s2 := param^.data^.sym^.name;
- s := s+tostr(length(s2))+s2;
- param := param^.next;
- end;
- cplusplusmangledname:=s;
- end;
- {$EndIf GDB}
- procedure tprocdef.setmangledname(const s : string);
- begin
- if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
- strdispose(_mangledname);
- setstring(_mangledname,s);
- {$ifdef UseBrowser}
- if assigned(parast) then
- begin
- stringdispose(parast^.name);
- parast^.name:=stringdup('args of '+s);
- end;
- if assigned(localst) then
- begin
- stringdispose(localst^.name);
- localst^.name:=stringdup('locals of '+s);
- end;
- {$endif UseBrowser}
- end;
- {***********************************************************************************
- TPROCVARDEF
- ***************************************************************************}
- constructor tprocvardef.init;
- begin
- inherited init;
- deftype:=procvardef;
- end;
- constructor tprocvardef.load;
- begin
- inherited load;
- deftype:=procvardef;
- end;
- procedure tprocvardef.write;
- begin
- {$ifndef NEWPPU}
- writebyte(ibprocvardef);
- {$endif}
- { here we cannot get a real good value so just give something }
- { plausible (PM) }
- {$ifdef StoreFPULevel}
- if is_fpu(retdef) then
- fpu_used:=3
- else
- fpu_used:=0;
- {$endif StoreFPULevel}
- inherited write;
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibprocvardef);
- {$endif}
- end;
- function tprocvardef.size : longint;
- begin
- if (options and pomethodpointer)=0 then
- size:=sizeof(pointer)
- else
- size:=2*sizeof(pointer);
- end;
- {$ifdef GDB}
- function tprocvardef.stabstring : pchar;
- var
- nss : pchar;
- i : word;
- vartyp : char;
- pst : pchar;
- param : pdefcoll;
- begin
- i := 0;
- param := para1;
- while assigned(param) do
- begin
- inc(i);
- param := param^.next;
- end;
- getmem(nss,1024);
- strpcopy(nss,'f'+retdef^.numberstring+','+tostr(i)+';');
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
- {Here we have lost the parameter names !!}
- pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
- strcat(nss,pst);
- strdispose(pst);
- param := param^.next;
- end;
- {strpcopy(strend(nss),';');}
- stabstring := strnew(nss);
- freemem(nss,1024);
- end;
- procedure tprocvardef.concatstabto(asmlist : paasmoutput);
- begin
- if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not is_def_stab_written then
- inherited concatstabto(asmlist);
- is_def_stab_written:=true;
- end;
- {$endif GDB}
- {***************************************************************************
- TOBJECTDEF
- ***************************************************************************}
- {$ifdef GDB}
- const
- vtabletype : word = 0;
- vtableassigned : boolean = false;
- {$endif GDB}
- constructor tobjectdef.init(const n : string;c : pobjectdef);
- begin
- tdef.init;
- deftype:=objectdef;
- childof:=c;
- options:=0;
- { privatesyms:=new(psymtable,init(objectsymtable));
- protectedsyms:=new(psymtable,init(objectsymtable)); }
- publicsyms:=new(psymtable,init(objectsymtable));
- publicsyms^.name := stringdup(n);
- { add the data of the anchestor class }
- if assigned(childof) then
- begin
- publicsyms^.datasize:=
- publicsyms^.datasize-4+childof^.publicsyms^.datasize;
- end;
- name:=stringdup(n);
- savesize := publicsyms^.datasize;
- publicsyms^.defowner:=@self;
- end;
- constructor tobjectdef.load;
- var
- oldread_member : boolean;
- begin
- tdef.load;
- deftype:=objectdef;
- savesize:=readlong;
- name:=stringdup(readstring);
- childof:=pobjectdef(readdefref);
- options:=readlong;
- oldread_member:=read_member;
- read_member:=true;
- if (options and (oo_hasprivate or oo_hasprotected))<>0 then
- object_options:=true;
- publicsyms:=new(psymtable,loadasstruct(objectsymtable));
- object_options:=false;
- publicsyms^.defowner:=@self;
- publicsyms^.datasize:=savesize;
- publicsyms^.name := stringdup(name^);
- read_member:=oldread_member;
- { handles the predefined class tobject }
- { the last TOBJECT which is loaded gets }
- { it ! }
- if (name^='TOBJECT') and not(cs_compilesystem in aktswitches) and
- isclass and (childof=pointer($ffffffff)) then
- class_tobject:=@self;
- end;
- procedure tobjectdef.check_forwards;
- begin
- publicsyms^.check_forwards;
- if (options and oo_isforward)<>0 then
- begin
- { ok, in future, the forward can be resolved }
- Message1(sym_e_class_forward_not_resolved,name^);
- options:=options and not(oo_isforward);
- end;
- end;
- destructor tobjectdef.done;
- begin
- {!!!!
- if assigned(privatesyms) then
- dispose(privatesyms,done);
- if assigned(protectedsyms) then
- dispose(protectedsyms,done); }
- if assigned(publicsyms) then
- dispose(publicsyms,done);
- if (options and oo_isforward)<>0 then
- Message1(sym_e_class_forward_not_resolved,name^);
- stringdispose(name);
- tdef.done;
- end;
- { true, if self inherits from d (or if they are equal) }
- function tobjectdef.isrelated(d : pobjectdef) : boolean;
- var
- hp : pobjectdef;
- begin
- hp:=@self;
- while assigned(hp) do
- begin
- if hp=d then
- begin
- isrelated:=true;
- exit;
- end;
- hp:=hp^.childof;
- end;
- isrelated:=false;
- end;
- function tobjectdef.size : longint;
- begin
- if (options and oois_class)<>0 then
- size:=sizeof(pointer)
- else
- size:=publicsyms^.datasize;
- end;
- procedure tobjectdef.deref;
- var
- hp : pdef;
- oldrecsyms : psymtable;
- begin
- resolvedef(pdef(childof));
- oldrecsyms:=aktrecordsymtable;
- aktrecordsymtable:=publicsyms;
- { nun die Definitionen dereferenzieren }
- hp:=publicsyms^.rootdef;
- while assigned(hp) do
- begin
- hp^.deref;
- {Besitzer setzen }
- hp^.owner:=publicsyms;
- hp:=hp^.next;
- end;
- {$ifdef tp}
- publicsyms^.foreach(derefsym);
- {$else}
- publicsyms^.foreach(@derefsym);
- {$endif}
- aktrecordsymtable:=oldrecsyms;
- end;
- function tobjectdef.vmt_mangledname : string;
- {DM: I get a nil pointer on the owner name. I don't know if this
- mayhappen, and I have therefore fixed the problem by doing nil pointer
- checks.}
- var s1,s2:string;
- begin
- if owner^.name=nil then
- s1:=''
- else
- s1:=owner^.name^;
- if name=nil then
- s2:=''
- else
- s2:=name^;
- vmt_mangledname:='VMT_'+s1+'$_'+s2;
- end;
- function tobjectdef.isclass : boolean;
- begin
- isclass:=(options and oois_class)<>0;
- end;
- procedure tobjectdef.write;
- var
- oldread_member : boolean;
- begin
- oldread_member:=read_member;
- read_member:=true;
- {$ifndef NEWPPU}
- writebyte(ibobjectdef);
- {$endif}
- tdef.write;
- writelong(size);
- writestring(name^);
- writedefref(childof);
- writelong(options);
- {$ifdef NEWPPU}
- ppufile^.writeentry(ibobjectdef);
- {$endif}
- if (options and (oo_hasprivate or oo_hasprotected))<>0 then
- object_options:=true;
- publicsyms^.writeasstruct;
- object_options:=false;
- read_member:=oldread_member;
- end;
- {$ifdef GDB}
- procedure addprocname(p :psym);
- var virtualind,argnames : string;
- news, newrec : pchar;
- pd,ipd : pprocdef;
- lindex : longint;
- para : pdefcoll;
- arglength : byte;
- sp : char;
- begin
- If p^.typ = procsym then
- begin
- pd := pprocsym(p)^.definition;
- { this will be used for full implementation of object stabs
- not yet done }
- ipd := pd;
- while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
- if (pd^.options and povirtualmethod) <> 0 then
- begin
- lindex := pd^.extnumber;
- {doesnt seem to be necessary
- lindex := lindex or $80000000;}
- virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
- end else virtualind := '.';
- { arguments are not listed here }
- {we don't need another definition}
- para := pd^.para1;
- argnames := '';
- while assigned(para) do
- begin
- if para^.data^.deftype = formaldef then
- begin
- if para^.paratyp=vs_var then
- argnames := argnames+'3var'
- else if para^.paratyp=vs_const then
- argnames:=argnames+'5const';
- end
- else
- begin
- { if the arg definition is like (v: ^byte;..
- there is no sym attached to data !!! }
- if assigned(para^.data^.sym) then
- begin
- arglength := length(para^.data^.sym^.name);
- argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
- end
- else
- begin
- argnames:=argnames+'11unnamedtype';
- end;
- end;
- para := para^.next;
- end;
- ipd^.is_def_stab_written := true;
- { here 2A must be changed for private and protected }
- { 0 is private 1 protected and 2 public }
- if (p^.properties and sp_private)<>0 then sp:='0'
- else if (p^.properties and sp_protected)<>0 then sp:='1'
- else sp:='2';
- newrec := strpnew(p^.name+'::'+ipd^.numberstring
- +'=##'+pd^.retdef^.numberstring+';:'+argnames+';'+sp+'A'
- +virtualind+';');
- { get spare place for a string at the end }
- if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
- begin
- getmem(news,stabrecsize+memsizeinc);
- strcopy(news,stabrecstring);
- freemem(stabrecstring,stabrecsize);
- stabrecsize:=stabrecsize+memsizeinc;
- stabrecstring:=news;
- end;
- strcat(StabRecstring,newrec);
- {freemem(newrec,memsizeinc); }
- strdispose(newrec);
- {This should be used for case !!}
- RecOffset := RecOffset + pd^.size;
- end;
- end;
- function tobjectdef.stabstring : pchar;
- var anc : pobjectdef;
- oldrec : pchar;
- oldrecsize : longint;
- str_end : string;
- begin
- oldrec := stabrecstring;
- oldrecsize:=stabrecsize;
- stabrecsize:=memsizeinc;
- GetMem(stabrecstring,stabrecsize);
- strpcopy(stabRecString,'s'+tostr(size));
- if assigned(childof) then
- {only one ancestor not virtual, public, at base offset 0 }
- { !1 , 0 2 0 , }
- strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
- {virtual table to implement yet}
- RecOffset := 0;
- {$ifdef tp}
- publicsyms^.foreach(addname);
- {$else}
- publicsyms^.foreach(@addname);
- {$endif tp}
- if (options and oo_hasvirtual) <> 0 then
- if not assigned(childof) or ((childof^.options and oo_hasvirtual) = 0) then
- begin
- str_end:='$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;';
- strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;');
- end;
- {$ifdef tp}
- publicsyms^.foreach(addprocname);
- {$else}
- publicsyms^.foreach(@addprocname);
- {$endif tp }
- if (options and oo_hasvirtual) <> 0 then
- begin
- anc := @self;
- while assigned(anc^.childof) and ((anc^.childof^.options and oo_hasvirtual) <> 0) do
- anc := anc^.childof;
- str_end:=';~%'+anc^.numberstring+';';
- end
- else
- str_end:=';';
- strpcopy(strend(stabrecstring),str_end);
- stabstring := strnew(StabRecString);
- freemem(stabrecstring,stabrecsize);
- stabrecstring := oldrec;
- stabrecsize:=oldrecsize;
- end;
- {$endif GDB}
- {****************************************************************************
- TERRORDEF
- ****************************************************************************}
- constructor terrordef.init;
- begin
- tdef.init;
- deftype:=errordef;
- end;
- {$ifdef GDB}
- function terrordef.stabstring : pchar;
- begin
- stabstring:=strpnew('error'+numberstring);
- end;
- {$endif GDB}
- {
- $Log$
- Revision 1.5 1998-06-04 23:52:01 peter
- * m68k compiles
- + .def file creation moved to gendef.pas so it could also be used
- for win32
- Revision 1.4 1998/06/04 09:55:45 pierre
- * demangled name of procsym reworked to become independant of the mangling scheme
- Come test_funcret improvements (not yet working)S: ----------------------------------------------------------------------
- Revision 1.3 1998/06/03 22:49:03 peter
- + wordbool,longbool
- * rename bis,von -> high,low
- * moved some systemunit loading/creating to psystem.pas
- Revision 1.2 1998/05/31 14:13:37 peter
- * fixed call bugs with assembler readers
- + OPR_SYMBOL to hold a symbol in the asm parser
- * fixed staticsymtable vars which were acessed through %ebp instead of
- name
- Revision 1.1 1998/05/27 19:45:09 peter
- * symtable.pas splitted into includefiles
- * symtable adapted for $ifdef NEWPPU
- }
-
|