symdef.pas 182 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symdef;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,globals,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,
  28. { ppu }
  29. symppu,ppu,
  30. { node }
  31. node,
  32. { aasm }
  33. aasmbase,aasmtai,cpubase,cpuinfo
  34. {$ifdef Delphi}
  35. ,dmisc
  36. {$endif}
  37. ;
  38. type
  39. {************************************************
  40. TDef
  41. ************************************************}
  42. tstoreddef = class(tdef)
  43. { persistent (available across units) rtti and init tables }
  44. rttitablesym,
  45. inittablesym : tsym; {trttisym}
  46. { local (per module) rtti and init tables }
  47. localrttilab : array[trttitype] of tasmlabel;
  48. { linked list of global definitions }
  49. nextglobal,
  50. previousglobal : tstoreddef;
  51. {$ifdef EXTDEBUG}
  52. fileinfo : tfileposinfo;
  53. {$endif}
  54. {$ifdef GDB}
  55. globalnb : word;
  56. is_def_stab_written : tdefstabstatus;
  57. {$endif GDB}
  58. constructor create;
  59. constructor ppuloaddef(ppufile:tcompilerppufile);
  60. destructor destroy;override;
  61. function getcopy : tstoreddef;virtual;
  62. procedure ppuwritedef(ppufile:tcompilerppufile);
  63. procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
  64. procedure deref;override;
  65. procedure derefimpl;override;
  66. function size:longint;override;
  67. function alignment:longint;override;
  68. function is_publishable : boolean;override;
  69. function needs_inittable : boolean;override;
  70. { debug }
  71. {$ifdef GDB}
  72. function stabstring : pchar;virtual;
  73. procedure concatstabto(asmlist : taasmoutput);virtual;
  74. function NumberString:string;
  75. procedure set_globalnb;virtual;
  76. function allstabstring : pchar;virtual;
  77. {$endif GDB}
  78. { rtti generation }
  79. procedure write_rtti_name;
  80. procedure write_rtti_data(rt:trttitype);virtual;
  81. procedure write_child_rtti_data(rt:trttitype);virtual;
  82. function get_rtti_label(rt:trttitype):tasmsymbol;
  83. { regvars }
  84. function is_intregable : boolean;
  85. function is_fpuregable : boolean;
  86. private
  87. savesize : longint;
  88. end;
  89. tparaitem = class(TLinkedListItem)
  90. paratype : ttype;
  91. parasym : tsym;
  92. defaultvalue : tsym; { tconstsym }
  93. paratyp : tvarspez;
  94. paraloc : tparalocation;
  95. {$ifdef EXTDEBUG}
  96. eqval : tequaltype;
  97. {$endif EXTDEBUG}
  98. end;
  99. { this is only here to override the count method,
  100. which can't be used }
  101. tparalinkedlist = class(tlinkedlist)
  102. function count:longint;
  103. end;
  104. tfiletyp = (ft_text,ft_typed,ft_untyped);
  105. tfiledef = class(tstoreddef)
  106. filetyp : tfiletyp;
  107. typedfiletype : ttype;
  108. constructor createtext;
  109. constructor createuntyped;
  110. constructor createtyped(const tt : ttype);
  111. constructor ppuload(ppufile:tcompilerppufile);
  112. procedure ppuwrite(ppufile:tcompilerppufile);override;
  113. procedure deref;override;
  114. function gettypename:string;override;
  115. function getmangledparaname:string;override;
  116. procedure setsize;
  117. { debug }
  118. {$ifdef GDB}
  119. function stabstring : pchar;override;
  120. procedure concatstabto(asmlist : taasmoutput);override;
  121. {$endif GDB}
  122. end;
  123. tvariantdef = class(tstoreddef)
  124. constructor create;
  125. constructor ppuload(ppufile:tcompilerppufile);
  126. function gettypename:string;override;
  127. procedure ppuwrite(ppufile:tcompilerppufile);override;
  128. procedure setsize;
  129. function needs_inittable : boolean;override;
  130. procedure write_rtti_data(rt:trttitype);override;
  131. {$ifdef GDB}
  132. procedure concatstabto(asmlist : taasmoutput);override;
  133. {$endif GDB}
  134. end;
  135. tformaldef = class(tstoreddef)
  136. constructor create;
  137. constructor ppuload(ppufile:tcompilerppufile);
  138. procedure ppuwrite(ppufile:tcompilerppufile);override;
  139. function gettypename:string;override;
  140. {$ifdef GDB}
  141. function stabstring : pchar;override;
  142. procedure concatstabto(asmlist : taasmoutput);override;
  143. {$endif GDB}
  144. end;
  145. tforwarddef = class(tstoreddef)
  146. tosymname : pstring;
  147. forwardpos : tfileposinfo;
  148. constructor create(const s:string;const pos : tfileposinfo);
  149. destructor destroy;override;
  150. function gettypename:string;override;
  151. end;
  152. terrordef = class(tstoreddef)
  153. constructor create;
  154. function gettypename:string;override;
  155. function getmangledparaname : string;override;
  156. { debug }
  157. {$ifdef GDB}
  158. function stabstring : pchar;override;
  159. procedure concatstabto(asmlist : taasmoutput);override;
  160. {$endif GDB}
  161. end;
  162. { tpointerdef and tclassrefdef should get a common
  163. base class, but I derived tclassrefdef from tpointerdef
  164. to avoid problems with bugs (FK)
  165. }
  166. tpointerdef = class(tstoreddef)
  167. pointertype : ttype;
  168. is_far : boolean;
  169. constructor create(const tt : ttype);
  170. constructor createfar(const tt : ttype);
  171. constructor ppuload(ppufile:tcompilerppufile);
  172. procedure ppuwrite(ppufile:tcompilerppufile);override;
  173. procedure deref;override;
  174. function gettypename:string;override;
  175. { debug }
  176. {$ifdef GDB}
  177. function stabstring : pchar;override;
  178. procedure concatstabto(asmlist : taasmoutput);override;
  179. {$endif GDB}
  180. end;
  181. tabstractrecorddef = class(tstoreddef)
  182. private
  183. Count : integer;
  184. FRTTIType : trttitype;
  185. {$ifdef GDB}
  186. StabRecString : pchar;
  187. StabRecSize : Integer;
  188. RecOffset : Integer;
  189. procedure addname(p : tnamedindexitem;arg:pointer);
  190. {$endif}
  191. procedure count_field_rtti(sym : tnamedindexitem;arg:pointer);
  192. procedure write_field_rtti(sym : tnamedindexitem;arg:pointer);
  193. procedure generate_field_rtti(sym : tnamedindexitem;arg:pointer);
  194. public
  195. symtable : tsymtable;
  196. function getsymtable(t:tgetsymtable):tsymtable;override;
  197. end;
  198. trecorddef = class(tabstractrecorddef)
  199. public
  200. isunion : boolean;
  201. constructor create(p : tsymtable);
  202. constructor ppuload(ppufile:tcompilerppufile);
  203. destructor destroy;override;
  204. procedure ppuwrite(ppufile:tcompilerppufile);override;
  205. procedure deref;override;
  206. function size:longint;override;
  207. function alignment : longint;override;
  208. function gettypename:string;override;
  209. { debug }
  210. {$ifdef GDB}
  211. function stabstring : pchar;override;
  212. procedure concatstabto(asmlist : taasmoutput);override;
  213. {$endif GDB}
  214. function needs_inittable : boolean;override;
  215. { rtti }
  216. procedure write_child_rtti_data(rt:trttitype);override;
  217. procedure write_rtti_data(rt:trttitype);override;
  218. end;
  219. tprocdef = class;
  220. timplementedinterfaces = class;
  221. tobjectdef = class(tabstractrecorddef)
  222. private
  223. sd : tprocdef;
  224. procedure _searchdestructor(sym : tnamedindexitem;arg:pointer);
  225. {$ifdef GDB}
  226. procedure addprocname(p :tnamedindexitem;arg:pointer);
  227. {$endif GDB}
  228. procedure count_published_properties(sym:tnamedindexitem;arg:pointer);
  229. procedure write_property_info(sym : tnamedindexitem;arg:pointer);
  230. procedure generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
  231. procedure count_published_fields(sym:tnamedindexitem;arg:pointer);
  232. procedure writefields(sym:tnamedindexitem;arg:pointer);
  233. public
  234. childof : tobjectdef;
  235. objname,
  236. objrealname : pstring;
  237. objectoptions : tobjectoptions;
  238. { to be able to have a variable vmt position }
  239. { and no vmt field for objects without virtuals }
  240. vmt_offset : longint;
  241. {$ifdef GDB}
  242. writing_class_record_stab : boolean;
  243. {$endif GDB}
  244. objecttype : tobjectdeftype;
  245. iidguid: pguid;
  246. iidstr: pstring;
  247. lastvtableindex: longint;
  248. { store implemented interfaces defs and name mappings }
  249. implementedinterfaces: timplementedinterfaces;
  250. constructor create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  251. constructor ppuload(ppufile:tcompilerppufile);
  252. destructor destroy;override;
  253. procedure ppuwrite(ppufile:tcompilerppufile);override;
  254. procedure deref;override;
  255. function size : longint;override;
  256. function alignment:longint;override;
  257. function vmtmethodoffset(index:longint):longint;
  258. function members_need_inittable : boolean;
  259. { this should be called when this class implements an interface }
  260. procedure prepareguid;
  261. function is_publishable : boolean;override;
  262. function needs_inittable : boolean;override;
  263. function vmt_mangledname : string;
  264. function rtti_name : string;
  265. procedure check_forwards;
  266. function is_related(d : tobjectdef) : boolean;
  267. function next_free_name_index : longint;
  268. procedure insertvmt;
  269. procedure set_parent(c : tobjectdef);
  270. function searchdestructor : tprocdef;
  271. { debug }
  272. {$ifdef GDB}
  273. function stabstring : pchar;override;
  274. procedure set_globalnb;override;
  275. function classnumberstring : string;
  276. procedure concatstabto(asmlist : taasmoutput);override;
  277. function allstabstring : pchar;override;
  278. {$endif GDB}
  279. { rtti }
  280. procedure write_child_rtti_data(rt:trttitype);override;
  281. procedure write_rtti_data(rt:trttitype);override;
  282. function generate_field_table : tasmlabel;
  283. end;
  284. timplementedinterfaces = class
  285. constructor create;
  286. destructor destroy; override;
  287. function count: longint;
  288. function interfaces(intfindex: longint): tobjectdef;
  289. function ioffsets(intfindex: longint): plongint;
  290. function searchintf(def: tdef): longint;
  291. procedure addintf(def: tdef);
  292. procedure deref;
  293. { add interface reference loaded from ppu }
  294. procedure addintfref(def: pointer);
  295. procedure clearmappings;
  296. procedure addmappings(intfindex: longint; const name, newname: string);
  297. function getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  298. procedure clearimplprocs;
  299. procedure addimplproc(intfindex: longint; procdef: tprocdef);
  300. function implproccount(intfindex: longint): longint;
  301. function implprocs(intfindex: longint; procindex: longint): tprocdef;
  302. function isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  303. private
  304. finterfaces: tindexarray;
  305. procedure checkindex(intfindex: longint);
  306. end;
  307. tclassrefdef = class(tpointerdef)
  308. constructor create(const t:ttype);
  309. constructor ppuload(ppufile:tcompilerppufile);
  310. procedure ppuwrite(ppufile:tcompilerppufile);override;
  311. function gettypename:string;override;
  312. { debug }
  313. {$ifdef GDB}
  314. function stabstring : pchar;override;
  315. procedure concatstabto(asmlist : taasmoutput);override;
  316. {$endif GDB}
  317. end;
  318. tarraydef = class(tstoreddef)
  319. lowrange,
  320. highrange : longint;
  321. rangetype : ttype;
  322. IsDynamicArray,
  323. IsVariant,
  324. IsConstructor,
  325. IsArrayOfConst : boolean;
  326. protected
  327. _elementtype : ttype;
  328. public
  329. function elesize : longint;
  330. constructor create(l,h : longint;const t : ttype);
  331. constructor ppuload(ppufile:tcompilerppufile);
  332. procedure ppuwrite(ppufile:tcompilerppufile);override;
  333. function gettypename:string;override;
  334. function getmangledparaname : string;override;
  335. procedure setelementtype(t: ttype);
  336. {$ifdef GDB}
  337. function stabstring : pchar;override;
  338. procedure concatstabto(asmlist : taasmoutput);override;
  339. {$endif GDB}
  340. procedure deref;override;
  341. function size : longint;override;
  342. function alignment : longint;override;
  343. { returns the label of the range check string }
  344. function needs_inittable : boolean;override;
  345. procedure write_child_rtti_data(rt:trttitype);override;
  346. procedure write_rtti_data(rt:trttitype);override;
  347. property elementtype : ttype Read _ElementType;
  348. end;
  349. torddef = class(tstoreddef)
  350. low,high : TConstExprInt;
  351. typ : tbasetype;
  352. constructor create(t : tbasetype;v,b : TConstExprInt);
  353. constructor ppuload(ppufile:tcompilerppufile);
  354. function getcopy : tstoreddef;override;
  355. procedure ppuwrite(ppufile:tcompilerppufile);override;
  356. function is_publishable : boolean;override;
  357. function gettypename:string;override;
  358. procedure setsize;
  359. { debug }
  360. {$ifdef GDB}
  361. function stabstring : pchar;override;
  362. {$endif GDB}
  363. { rtti }
  364. procedure write_rtti_data(rt:trttitype);override;
  365. end;
  366. tfloatdef = class(tstoreddef)
  367. typ : tfloattype;
  368. constructor create(t : tfloattype);
  369. constructor ppuload(ppufile:tcompilerppufile);
  370. function getcopy : tstoreddef;override;
  371. procedure ppuwrite(ppufile:tcompilerppufile);override;
  372. function gettypename:string;override;
  373. function is_publishable : boolean;override;
  374. procedure setsize;
  375. { debug }
  376. {$ifdef GDB}
  377. function stabstring : pchar;override;
  378. {$endif GDB}
  379. { rtti }
  380. procedure write_rtti_data(rt:trttitype);override;
  381. end;
  382. tabstractprocdef = class(tstoreddef)
  383. { saves a definition to the return type }
  384. rettype : ttype;
  385. para : tparalinkedlist;
  386. selfpara : tparaitem;
  387. proctypeoption : tproctypeoption;
  388. proccalloption : tproccalloption;
  389. procoptions : tprocoptions;
  390. maxparacount,
  391. minparacount : byte;
  392. symtablelevel : byte;
  393. fpu_used : byte; { how many stack fpu must be empty }
  394. constructor create;
  395. constructor ppuload(ppufile:tcompilerppufile);
  396. destructor destroy;override;
  397. procedure ppuwrite(ppufile:tcompilerppufile);override;
  398. procedure deref;override;
  399. function concatpara(const tt:ttype;sym : tsym;vsp : tvarspez;defval:tsym):tparaitem;
  400. function para_size(alignsize:longint) : longint;
  401. function typename_paras : string;
  402. procedure test_if_fpu_result;
  403. function is_methodpointer:boolean;virtual;
  404. function is_addressonly:boolean;virtual;
  405. { debug }
  406. {$ifdef GDB}
  407. function stabstring : pchar;override;
  408. procedure concatstabto(asmlist : taasmoutput);override;
  409. {$endif GDB}
  410. end;
  411. tprocvardef = class(tabstractprocdef)
  412. constructor create;
  413. constructor ppuload(ppufile:tcompilerppufile);
  414. procedure ppuwrite(ppufile:tcompilerppufile);override;
  415. function size : longint;override;
  416. function gettypename:string;override;
  417. function is_publishable : boolean;override;
  418. function is_methodpointer:boolean;override;
  419. function is_addressonly:boolean;override;
  420. { debug }
  421. {$ifdef GDB}
  422. function stabstring : pchar;override;
  423. procedure concatstabto(asmlist : taasmoutput); override;
  424. {$endif GDB}
  425. { rtti }
  426. procedure write_rtti_data(rt:trttitype);override;
  427. end;
  428. tmessageinf = record
  429. case integer of
  430. 0 : (str : pchar);
  431. 1 : (i : longint);
  432. end;
  433. tprocdef = class(tabstractprocdef)
  434. private
  435. _mangledname : pstring;
  436. {$ifdef GDB}
  437. isstabwritten : boolean;
  438. {$endif GDB}
  439. public
  440. extnumber : word;
  441. overloadnumber : word;
  442. messageinf : tmessageinf;
  443. {$ifndef EXTDEBUG}
  444. { where is this function defined, needed here because there
  445. is only one symbol for all overloaded functions
  446. EXTDEBUG has fileinfo in tdef (PFV) }
  447. fileinfo : tfileposinfo;
  448. {$endif}
  449. { symbol owning this definition }
  450. procsym : tsym;
  451. { alias names }
  452. aliasnames : tstringlist;
  453. { symtables }
  454. parast,
  455. localst : tsymtable;
  456. funcretsym : tsym;
  457. { next is only used to check if RESULT is accessed,
  458. not stored in a tnode }
  459. resultfuncretsym : tsym;
  460. { browser info }
  461. lastref,
  462. defref,
  463. lastwritten : tref;
  464. refcount : longint;
  465. _class : tobjectdef;
  466. { it's a tree, but this not easy to handle }
  467. { used for inlined procs }
  468. code : tnode;
  469. { info about register variables (JM) }
  470. regvarinfo: pointer;
  471. { true, if the procedure is only declared }
  472. { (forward procedure) }
  473. forwarddef,
  474. { true if the procedure is declared in the interface }
  475. interfacedef : boolean;
  476. { true if the procedure has a forward declaration }
  477. hasforward : boolean;
  478. { check the problems of manglednames }
  479. has_mangledname : boolean;
  480. { small set which contains the modified registers }
  481. usedintregisters:Tsupregset;
  482. usedotherregisters:Tregisterset;
  483. constructor create;
  484. constructor ppuload(ppufile:tcompilerppufile);
  485. destructor destroy;override;
  486. procedure ppuwrite(ppufile:tcompilerppufile);override;
  487. procedure deref;override;
  488. procedure derefimpl;override;
  489. function getsymtable(t:tgetsymtable):tsymtable;override;
  490. function haspara:boolean;
  491. function gettypename : string;override;
  492. function mangledname : string;
  493. procedure setmangledname(const s : string);
  494. procedure load_references(ppufile:tcompilerppufile;locals:boolean);
  495. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  496. { inserts the local symbol table, if this is not
  497. no local symbol table is built. Should be called only
  498. when we are sure that a local symbol table will be required.
  499. }
  500. procedure insert_localst;
  501. function fullprocname:string;
  502. function fullprocnamewithret:string;
  503. function cplusplusmangledname : string;
  504. function is_methodpointer:boolean;override;
  505. function is_addressonly:boolean;override;
  506. { debug }
  507. {$ifdef GDB}
  508. function stabstring : pchar;override;
  509. procedure concatstabto(asmlist : taasmoutput);override;
  510. {$endif GDB}
  511. end;
  512. { single linked list of overloaded procs }
  513. pprocdeflist = ^tprocdeflist;
  514. tprocdeflist = record
  515. def : tprocdef;
  516. next : pprocdeflist;
  517. end;
  518. tstringdef = class(tstoreddef)
  519. string_typ : tstringtype;
  520. len : longint;
  521. constructor createshort(l : byte);
  522. constructor loadshort(ppufile:tcompilerppufile);
  523. constructor createlong(l : longint);
  524. constructor loadlong(ppufile:tcompilerppufile);
  525. constructor createansi(l : longint);
  526. constructor loadansi(ppufile:tcompilerppufile);
  527. constructor createwide(l : longint);
  528. constructor loadwide(ppufile:tcompilerppufile);
  529. function getcopy : tstoreddef;override;
  530. function stringtypname:string;
  531. function size : longint;override;
  532. procedure ppuwrite(ppufile:tcompilerppufile);override;
  533. function gettypename:string;override;
  534. function getmangledparaname:string;override;
  535. function is_publishable : boolean;override;
  536. { debug }
  537. {$ifdef GDB}
  538. function stabstring : pchar;override;
  539. procedure concatstabto(asmlist : taasmoutput);override;
  540. {$endif GDB}
  541. { init/final }
  542. function needs_inittable : boolean;override;
  543. { rtti }
  544. procedure write_rtti_data(rt:trttitype);override;
  545. end;
  546. tenumdef = class(tstoreddef)
  547. minval,
  548. maxval : longint;
  549. has_jumps : boolean;
  550. firstenum : tsym; {tenumsym}
  551. basedef : tenumdef;
  552. constructor create;
  553. constructor create_subrange(_basedef:tenumdef;_min,_max:longint);
  554. constructor ppuload(ppufile:tcompilerppufile);
  555. destructor destroy;override;
  556. procedure ppuwrite(ppufile:tcompilerppufile);override;
  557. procedure deref;override;
  558. function gettypename:string;override;
  559. function is_publishable : boolean;override;
  560. procedure calcsavesize;
  561. procedure setmax(_max:longint);
  562. procedure setmin(_min:longint);
  563. function min:longint;
  564. function max:longint;
  565. { debug }
  566. {$ifdef GDB}
  567. function stabstring : pchar;override;
  568. {$endif GDB}
  569. { rtti }
  570. procedure write_rtti_data(rt:trttitype);override;
  571. procedure write_child_rtti_data(rt:trttitype);override;
  572. private
  573. procedure correct_owner_symtable;
  574. end;
  575. tsetdef = class(tstoreddef)
  576. elementtype : ttype;
  577. settype : tsettype;
  578. constructor create(const t:ttype;high : longint);
  579. constructor ppuload(ppufile:tcompilerppufile);
  580. destructor destroy;override;
  581. procedure ppuwrite(ppufile:tcompilerppufile);override;
  582. procedure deref;override;
  583. function gettypename:string;override;
  584. function is_publishable : boolean;override;
  585. procedure changesettype(s:tsettype);
  586. { debug }
  587. {$ifdef GDB}
  588. function stabstring : pchar;override;
  589. procedure concatstabto(asmlist : taasmoutput);override;
  590. {$endif GDB}
  591. { rtti }
  592. procedure write_rtti_data(rt:trttitype);override;
  593. procedure write_child_rtti_data(rt:trttitype);override;
  594. end;
  595. Tdefmatch=(dm_exact,dm_equal,dm_convertl1);
  596. var
  597. aktobjectdef : tobjectdef; { used for private functions check !! }
  598. firstglobaldef, { linked list of all globals defs }
  599. lastglobaldef : tstoreddef; { used to reset stabs/ranges }
  600. {$ifdef GDB}
  601. { for STAB debugging }
  602. globaltypecount : word;
  603. pglobaltypecount : pword;
  604. {$endif GDB}
  605. { default types }
  606. generrortype, { error in definition }
  607. voidpointertype, { pointer for Void-Pointerdef }
  608. charpointertype, { pointer for Char-Pointerdef }
  609. voidfarpointertype,
  610. cformaltype, { unique formal definition }
  611. voidtype, { Pointer to Void (procedure) }
  612. cchartype, { Pointer to Char }
  613. cwidechartype, { Pointer to WideChar }
  614. booltype, { pointer to boolean type }
  615. u8bittype, { Pointer to 8-Bit unsigned }
  616. u16bittype, { Pointer to 16-Bit unsigned }
  617. u32bittype, { Pointer to 32-Bit unsigned }
  618. s32bittype, { Pointer to 32-Bit signed }
  619. cu64bittype, { pointer to 64 bit unsigned def }
  620. cs64bittype, { pointer to 64 bit signed def, }
  621. s32floattype, { pointer for realconstn }
  622. s64floattype, { pointer for realconstn }
  623. s80floattype, { pointer to type of temp. floats }
  624. s64currencytype, { pointer to a currency type }
  625. s32fixedtype, { pointer to type of temp. fixed }
  626. cshortstringtype, { pointer to type of short string const }
  627. clongstringtype, { pointer to type of long string const }
  628. cansistringtype, { pointer to type of ansi string const }
  629. cwidestringtype, { pointer to type of wide string const }
  630. openshortstringtype, { pointer to type of an open shortstring,
  631. needed for readln() }
  632. openchararraytype, { pointer to type of an open array of char,
  633. needed for readln() }
  634. cfiletype, { get the same definition for all file }
  635. { used for stabs }
  636. { we use only one variant def }
  637. cvarianttype,
  638. { unsigned ord type with the same size as a pointer }
  639. ordpointertype,
  640. pvmttype : ttype; { type of classrefs, used for stabs }
  641. class_tobject : tobjectdef; { pointer to the anchestor of all classes }
  642. interface_iunknown : tobjectdef; { KAZ: pointer to the ancestor }
  643. rec_tguid : trecorddef; { KAZ: pointer to the TGUID type }
  644. { of all interfaces }
  645. const
  646. {$ifdef i386}
  647. pbestrealtype : ^ttype = @s80floattype;
  648. {$endif}
  649. {$ifdef x86_64}
  650. pbestrealtype : ^ttype = @s80floattype;
  651. {$endif}
  652. {$ifdef m68k}
  653. pbestrealtype : ^ttype = @s64floattype;
  654. {$endif}
  655. {$ifdef alpha}
  656. pbestrealtype : ^ttype = @s64floattype;
  657. {$endif}
  658. {$ifdef powerpc}
  659. pbestrealtype : ^ttype = @s64floattype;
  660. {$endif}
  661. {$ifdef ia64}
  662. pbestrealtype : ^ttype = @s64floattype;
  663. {$endif}
  664. {$ifdef SPARC}
  665. pbestrealtype : ^ttype = @s64floattype;
  666. {$endif SPARC}
  667. {$ifdef vis}
  668. pbestrealtype : ^ttype = @s64floattype;
  669. {$endif vis}
  670. function mangledname_prefix(typeprefix:string;st:tsymtable):string;
  671. {$ifdef GDB}
  672. { GDB Helpers }
  673. function typeglobalnumber(const s : string) : string;
  674. {$endif GDB}
  675. { should be in the types unit, but the types unit uses the node stuff :( }
  676. function is_interfacecom(def: tdef): boolean;
  677. function is_interfacecorba(def: tdef): boolean;
  678. function is_interface(def: tdef): boolean;
  679. function is_object(def: tdef): boolean;
  680. function is_class(def: tdef): boolean;
  681. function is_cppclass(def: tdef): boolean;
  682. function is_class_or_interface(def: tdef): boolean;
  683. procedure reset_global_defs;
  684. implementation
  685. uses
  686. {$ifdef Delphi}
  687. sysutils,
  688. {$else Delphi}
  689. strings,
  690. {$endif Delphi}
  691. { global }
  692. verbose,
  693. { target }
  694. aasmcpu,
  695. systems,
  696. { symtable }
  697. symsym,symtable,paramgr,
  698. symutil,defutil,
  699. { module }
  700. {$ifdef GDB}
  701. gdb,
  702. {$endif GDB}
  703. fmodule,
  704. { other }
  705. gendef
  706. ;
  707. {****************************************************************************
  708. Helpers
  709. ****************************************************************************}
  710. function mangledname_prefix(typeprefix:string;st:tsymtable):string;
  711. var
  712. s,
  713. prefix : string;
  714. begin
  715. prefix:='';
  716. if not assigned(st) then
  717. internalerror(200204212);
  718. { sub procedures }
  719. while (st.symtabletype=localsymtable) do
  720. begin
  721. if st.defowner.deftype<>procdef then
  722. internalerror(200204173);
  723. s:=tprocdef(st.defowner).procsym.name;
  724. if tprocdef(st.defowner).overloadnumber>0 then
  725. s:=s+'$'+tostr(tprocdef(st.defowner).overloadnumber);
  726. prefix:=s+'$'+prefix;
  727. st:=st.defowner.owner;
  728. end;
  729. { object/classes symtable }
  730. if (st.symtabletype=objectsymtable) then
  731. begin
  732. if st.defowner.deftype<>objectdef then
  733. internalerror(200204174);
  734. prefix:=tobjectdef(st.defowner).objname^+'_$_'+prefix;
  735. st:=st.defowner.owner;
  736. end;
  737. { symtable must now be static or global }
  738. if not(st.symtabletype in [staticsymtable,globalsymtable]) then
  739. internalerror(200204175);
  740. mangledname_prefix:=typeprefix+'_'+st.name^+'_'+prefix;
  741. end;
  742. {$ifdef GDB}
  743. procedure forcestabto(asmlist : taasmoutput; pd : tdef);
  744. begin
  745. if tstoreddef(pd).is_def_stab_written = not_written then
  746. begin
  747. if assigned(pd.typesym) then
  748. ttypesym(pd.typesym).isusedinstab := true;
  749. tstoreddef(pd).concatstabto(asmlist);
  750. end;
  751. end;
  752. {$endif GDB}
  753. {****************************************************************************
  754. TDEF (base class for definitions)
  755. ****************************************************************************}
  756. constructor tstoreddef.create;
  757. begin
  758. inherited create;
  759. savesize := 0;
  760. {$ifdef EXTDEBUG}
  761. fileinfo := aktfilepos;
  762. {$endif}
  763. if registerdef then
  764. symtablestack.registerdef(self);
  765. {$ifdef GDB}
  766. is_def_stab_written := not_written;
  767. globalnb := 0;
  768. {$endif GDB}
  769. if assigned(lastglobaldef) then
  770. begin
  771. lastglobaldef.nextglobal := self;
  772. previousglobal:=lastglobaldef;
  773. end
  774. else
  775. begin
  776. firstglobaldef := self;
  777. previousglobal := nil;
  778. end;
  779. lastglobaldef := self;
  780. nextglobal := nil;
  781. fillchar(localrttilab,sizeof(localrttilab),0);
  782. end;
  783. constructor tstoreddef.ppuloaddef(ppufile:tcompilerppufile);
  784. begin
  785. inherited create;
  786. {$ifdef EXTDEBUG}
  787. fillchar(fileinfo,sizeof(fileinfo),0);
  788. {$endif}
  789. {$ifdef GDB}
  790. is_def_stab_written := not_written;
  791. globalnb := 0;
  792. {$endif GDB}
  793. if assigned(lastglobaldef) then
  794. begin
  795. lastglobaldef.nextglobal := self;
  796. previousglobal:=lastglobaldef;
  797. end
  798. else
  799. begin
  800. firstglobaldef := self;
  801. previousglobal:=nil;
  802. end;
  803. lastglobaldef := self;
  804. nextglobal := nil;
  805. fillchar(localrttilab,sizeof(localrttilab),0);
  806. { load }
  807. indexnr:=ppufile.getword;
  808. typesym:=ttypesym(pointer(ppufile.getderef));
  809. ppufile.getsmallset(defoptions);
  810. if df_has_rttitable in defoptions then
  811. rttitablesym:=tsym(ppufile.getderef);
  812. if df_has_inittable in defoptions then
  813. inittablesym:=tsym(ppufile.getderef);
  814. end;
  815. destructor tstoreddef.destroy;
  816. begin
  817. { first element ? }
  818. if not(assigned(previousglobal)) then
  819. begin
  820. firstglobaldef := nextglobal;
  821. if assigned(firstglobaldef) then
  822. firstglobaldef.previousglobal:=nil;
  823. end
  824. else
  825. begin
  826. { remove reference in the element before }
  827. previousglobal.nextglobal:=nextglobal;
  828. end;
  829. { last element ? }
  830. if not(assigned(nextglobal)) then
  831. begin
  832. lastglobaldef := previousglobal;
  833. if assigned(lastglobaldef) then
  834. lastglobaldef.nextglobal:=nil;
  835. end
  836. else
  837. nextglobal.previousglobal:=previousglobal;
  838. previousglobal:=nil;
  839. nextglobal:=nil;
  840. end;
  841. function tstoreddef.getcopy : tstoreddef;
  842. begin
  843. Message(sym_e_cant_create_unique_type);
  844. getcopy:=nil;
  845. end;
  846. procedure tstoreddef.ppuwritedef(ppufile:tcompilerppufile);
  847. begin
  848. ppufile.putword(indexnr);
  849. ppufile.putderef(typesym);
  850. ppufile.putsmallset(defoptions);
  851. if df_has_rttitable in defoptions then
  852. ppufile.putderef(rttitablesym);
  853. if df_has_inittable in defoptions then
  854. ppufile.putderef(inittablesym);
  855. {$ifdef GDB}
  856. if globalnb = 0 then
  857. begin
  858. if assigned(owner) then
  859. globalnb := owner.getnewtypecount
  860. else
  861. begin
  862. globalnb := PGlobalTypeCount^;
  863. Inc(PGlobalTypeCount^);
  864. end;
  865. end;
  866. {$endif GDB}
  867. end;
  868. procedure tstoreddef.deref;
  869. begin
  870. resolvesym(pointer(typesym));
  871. resolvesym(pointer(rttitablesym));
  872. resolvesym(pointer(inittablesym));
  873. end;
  874. procedure tstoreddef.derefimpl;
  875. begin
  876. end;
  877. function tstoreddef.size : longint;
  878. begin
  879. size:=savesize;
  880. end;
  881. function tstoreddef.alignment : longint;
  882. begin
  883. { normal alignment by default }
  884. alignment:=0;
  885. end;
  886. {$ifdef GDB}
  887. procedure tstoreddef.set_globalnb;
  888. begin
  889. globalnb :=PGlobalTypeCount^;
  890. inc(PglobalTypeCount^);
  891. end;
  892. function tstoreddef.stabstring : pchar;
  893. begin
  894. stabstring := strpnew('t'+numberstring+';');
  895. end;
  896. function tstoreddef.numberstring : string;
  897. var table : tsymtable;
  898. begin
  899. {formal def have no type !}
  900. if deftype = formaldef then
  901. begin
  902. numberstring := tstoreddef(voidtype.def).numberstring;
  903. exit;
  904. end;
  905. if (not assigned(typesym)) or (not ttypesym(typesym).isusedinstab) then
  906. begin
  907. {set even if debuglist is not defined}
  908. if assigned(typesym) then
  909. ttypesym(typesym).isusedinstab := true;
  910. if assigned(debuglist) and (is_def_stab_written = not_written) then
  911. concatstabto(debuglist);
  912. end;
  913. if not (cs_gdb_dbx in aktglobalswitches) then
  914. begin
  915. if globalnb = 0 then
  916. set_globalnb;
  917. numberstring := tostr(globalnb);
  918. end
  919. else
  920. begin
  921. if globalnb = 0 then
  922. begin
  923. if assigned(owner) then
  924. globalnb := owner.getnewtypecount
  925. else
  926. begin
  927. globalnb := PGlobalTypeCount^;
  928. Inc(PGlobalTypeCount^);
  929. end;
  930. end;
  931. if assigned(typesym) then
  932. begin
  933. table := ttypesym(typesym).owner;
  934. if table.unitid > 0 then
  935. numberstring := '('+tostr(table.unitid)+','+tostr(tstoreddef(ttypesym(typesym).restype.def).globalnb)+')'
  936. else
  937. numberstring := tostr(globalnb);
  938. exit;
  939. end;
  940. numberstring := tostr(globalnb);
  941. end;
  942. end;
  943. function tstoreddef.allstabstring : pchar;
  944. var stabchar : string[2];
  945. ss,st : pchar;
  946. sname : string;
  947. sym_line_no : longint;
  948. begin
  949. ss := stabstring;
  950. getmem(st,strlen(ss)+512);
  951. stabchar := 't';
  952. if deftype in tagtypes then
  953. stabchar := 'Tt';
  954. if assigned(typesym) then
  955. begin
  956. sname := ttypesym(typesym).name;
  957. sym_line_no:=ttypesym(typesym).fileinfo.line;
  958. end
  959. else
  960. begin
  961. sname := ' ';
  962. sym_line_no:=0;
  963. end;
  964. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  965. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  966. allstabstring := strnew(st);
  967. freemem(st,strlen(ss)+512);
  968. strdispose(ss);
  969. end;
  970. procedure tstoreddef.concatstabto(asmlist : taasmoutput);
  971. var stab_str : pchar;
  972. begin
  973. if ((typesym = nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  974. and (is_def_stab_written = not_written) then
  975. begin
  976. If cs_gdb_dbx in aktglobalswitches then
  977. begin
  978. { otherwise you get two of each def }
  979. If assigned(typesym) then
  980. begin
  981. if ttypesym(typesym).typ=symconst.typesym then
  982. ttypesym(typesym).isusedinstab:=true;
  983. if (ttypesym(typesym).owner = nil) or
  984. ((ttypesym(typesym).owner.symtabletype = globalsymtable) and
  985. tglobalsymtable(ttypesym(typesym).owner).dbx_count_ok) then
  986. begin
  987. {with DBX we get the definition from the other objects }
  988. is_def_stab_written := written;
  989. exit;
  990. end;
  991. end;
  992. end;
  993. { to avoid infinite loops }
  994. is_def_stab_written := being_written;
  995. stab_str := allstabstring;
  996. asmList.concat(Tai_stabs.Create(stab_str));
  997. is_def_stab_written := written;
  998. end;
  999. end;
  1000. {$endif GDB}
  1001. procedure tstoreddef.write_rtti_name;
  1002. var
  1003. str : string;
  1004. begin
  1005. { name }
  1006. if assigned(typesym) then
  1007. begin
  1008. str:=ttypesym(typesym).realname;
  1009. rttiList.concat(Tai_string.Create(chr(length(str))+str));
  1010. end
  1011. else
  1012. rttiList.concat(Tai_string.Create(#0))
  1013. end;
  1014. procedure tstoreddef.write_rtti_data(rt:trttitype);
  1015. begin
  1016. rttilist.concat(tai_const.create_8bit(tkUnknown));
  1017. write_rtti_name;
  1018. end;
  1019. procedure tstoreddef.write_child_rtti_data(rt:trttitype);
  1020. begin
  1021. end;
  1022. function tstoreddef.get_rtti_label(rt:trttitype) : tasmsymbol;
  1023. begin
  1024. { try to reuse persistent rtti data }
  1025. if (rt=fullrtti) and (df_has_rttitable in defoptions) then
  1026. get_rtti_label:=trttisym(rttitablesym).get_label
  1027. else
  1028. if (rt=initrtti) and (df_has_inittable in defoptions) then
  1029. get_rtti_label:=trttisym(inittablesym).get_label
  1030. else
  1031. begin
  1032. if not assigned(localrttilab[rt]) then
  1033. begin
  1034. objectlibrary.getdatalabel(localrttilab[rt]);
  1035. write_child_rtti_data(rt);
  1036. if (cs_create_smart in aktmoduleswitches) then
  1037. rttiList.concat(Tai_cut.Create);
  1038. rttiList.concat(Tai_align.create(const_align(pointer_size)));
  1039. rttiList.concat(Tai_symbol.Create(localrttilab[rt],0));
  1040. write_rtti_data(rt);
  1041. rttiList.concat(Tai_symbol_end.Create(localrttilab[rt]));
  1042. end;
  1043. get_rtti_label:=localrttilab[rt];
  1044. end;
  1045. end;
  1046. { returns true, if the definition can be published }
  1047. function tstoreddef.is_publishable : boolean;
  1048. begin
  1049. is_publishable:=false;
  1050. end;
  1051. { needs an init table }
  1052. function tstoreddef.needs_inittable : boolean;
  1053. begin
  1054. needs_inittable:=false;
  1055. end;
  1056. function tstoreddef.is_intregable : boolean;
  1057. begin
  1058. is_intregable:=false;
  1059. case deftype of
  1060. pointerdef,
  1061. enumdef:
  1062. is_intregable:=true;
  1063. procvardef :
  1064. is_intregable:=not(po_methodpointer in tprocvardef(self).procoptions);
  1065. orddef :
  1066. case torddef(self).typ of
  1067. bool8bit,bool16bit,bool32bit,
  1068. u8bit,u16bit,u32bit,
  1069. s8bit,s16bit,s32bit:
  1070. is_intregable:=true;
  1071. end;
  1072. setdef:
  1073. is_intregable:=(tsetdef(self).settype=smallset);
  1074. end;
  1075. end;
  1076. function tstoreddef.is_fpuregable : boolean;
  1077. begin
  1078. is_fpuregable:=(deftype=floatdef);
  1079. end;
  1080. {****************************************************************************
  1081. TPARALINKEDLIST
  1082. ****************************************************************************}
  1083. function tparalinkedlist.count:longint;
  1084. begin
  1085. { You must use tabstractprocdef.minparacount and .maxparacount instead }
  1086. internalerror(432432978);
  1087. count:=0;
  1088. end;
  1089. {****************************************************************************
  1090. Tstringdef
  1091. ****************************************************************************}
  1092. constructor tstringdef.createshort(l : byte);
  1093. begin
  1094. inherited create;
  1095. string_typ:=st_shortstring;
  1096. deftype:=stringdef;
  1097. len:=l;
  1098. savesize:=len+1;
  1099. end;
  1100. constructor tstringdef.loadshort(ppufile:tcompilerppufile);
  1101. begin
  1102. inherited ppuloaddef(ppufile);
  1103. string_typ:=st_shortstring;
  1104. deftype:=stringdef;
  1105. len:=ppufile.getbyte;
  1106. savesize:=len+1;
  1107. end;
  1108. constructor tstringdef.createlong(l : longint);
  1109. begin
  1110. inherited create;
  1111. string_typ:=st_longstring;
  1112. deftype:=stringdef;
  1113. len:=l;
  1114. savesize:=POINTER_SIZE;
  1115. end;
  1116. constructor tstringdef.loadlong(ppufile:tcompilerppufile);
  1117. begin
  1118. inherited ppuloaddef(ppufile);
  1119. deftype:=stringdef;
  1120. string_typ:=st_longstring;
  1121. len:=ppufile.getlongint;
  1122. savesize:=POINTER_SIZE;
  1123. end;
  1124. constructor tstringdef.createansi(l : longint);
  1125. begin
  1126. inherited create;
  1127. string_typ:=st_ansistring;
  1128. deftype:=stringdef;
  1129. len:=l;
  1130. savesize:=POINTER_SIZE;
  1131. end;
  1132. constructor tstringdef.loadansi(ppufile:tcompilerppufile);
  1133. begin
  1134. inherited ppuloaddef(ppufile);
  1135. deftype:=stringdef;
  1136. string_typ:=st_ansistring;
  1137. len:=ppufile.getlongint;
  1138. savesize:=POINTER_SIZE;
  1139. end;
  1140. constructor tstringdef.createwide(l : longint);
  1141. begin
  1142. inherited create;
  1143. string_typ:=st_widestring;
  1144. deftype:=stringdef;
  1145. len:=l;
  1146. savesize:=POINTER_SIZE;
  1147. end;
  1148. constructor tstringdef.loadwide(ppufile:tcompilerppufile);
  1149. begin
  1150. inherited ppuloaddef(ppufile);
  1151. deftype:=stringdef;
  1152. string_typ:=st_widestring;
  1153. len:=ppufile.getlongint;
  1154. savesize:=POINTER_SIZE;
  1155. end;
  1156. function tstringdef.getcopy : tstoreddef;
  1157. begin
  1158. result:=tstringdef.create;
  1159. result.deftype:=stringdef;
  1160. tstringdef(result).string_typ:=string_typ;
  1161. tstringdef(result).len:=len;
  1162. tstringdef(result).savesize:=savesize;
  1163. end;
  1164. function tstringdef.stringtypname:string;
  1165. const
  1166. typname:array[tstringtype] of string[8]=('',
  1167. 'shortstr','longstr','ansistr','widestr'
  1168. );
  1169. begin
  1170. stringtypname:=typname[string_typ];
  1171. end;
  1172. function tstringdef.size : longint;
  1173. begin
  1174. size:=savesize;
  1175. end;
  1176. procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
  1177. begin
  1178. inherited ppuwritedef(ppufile);
  1179. if string_typ=st_shortstring then
  1180. begin
  1181. {$ifdef extdebug}
  1182. if len > 255 then internalerror(12122002);
  1183. {$endif}
  1184. ppufile.putbyte(byte(len))
  1185. end
  1186. else
  1187. ppufile.putlongint(len);
  1188. case string_typ of
  1189. st_shortstring : ppufile.writeentry(ibshortstringdef);
  1190. st_longstring : ppufile.writeentry(iblongstringdef);
  1191. st_ansistring : ppufile.writeentry(ibansistringdef);
  1192. st_widestring : ppufile.writeentry(ibwidestringdef);
  1193. end;
  1194. end;
  1195. {$ifdef GDB}
  1196. function tstringdef.stabstring : pchar;
  1197. var
  1198. bytest,charst,longst : string;
  1199. begin
  1200. case string_typ of
  1201. st_shortstring:
  1202. begin
  1203. charst := typeglobalnumber('char');
  1204. { this is what I found in stabs.texinfo but
  1205. gdb 4.12 for go32 doesn't understand that !! }
  1206. {$IfDef GDBknowsstrings}
  1207. stabstring := strpnew('n'+charst+';'+tostr(len));
  1208. {$else}
  1209. bytest := typeglobalnumber('byte');
  1210. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  1211. +',0,8;st:ar'+bytest
  1212. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  1213. {$EndIf}
  1214. end;
  1215. st_longstring:
  1216. begin
  1217. charst := typeglobalnumber('char');
  1218. { this is what I found in stabs.texinfo but
  1219. gdb 4.12 for go32 doesn't understand that !! }
  1220. {$IfDef GDBknowsstrings}
  1221. stabstring := strpnew('n'+charst+';'+tostr(len));
  1222. {$else}
  1223. bytest := typeglobalnumber('byte');
  1224. longst := typeglobalnumber('longint');
  1225. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  1226. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  1227. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  1228. {$EndIf}
  1229. end;
  1230. st_ansistring:
  1231. begin
  1232. { an ansi string looks like a pchar easy !! }
  1233. stabstring:=strpnew('*'+typeglobalnumber('char'));
  1234. end;
  1235. st_widestring:
  1236. begin
  1237. { an ansi string looks like a pwidechar easy !! }
  1238. stabstring:=strpnew('*'+typeglobalnumber('widechar'));
  1239. end;
  1240. end;
  1241. end;
  1242. procedure tstringdef.concatstabto(asmlist : taasmoutput);
  1243. begin
  1244. inherited concatstabto(asmlist);
  1245. end;
  1246. {$endif GDB}
  1247. function tstringdef.needs_inittable : boolean;
  1248. begin
  1249. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  1250. end;
  1251. function tstringdef.gettypename : string;
  1252. const
  1253. names : array[tstringtype] of string[20] = ('',
  1254. 'ShortString','LongString','AnsiString','WideString');
  1255. begin
  1256. gettypename:=names[string_typ];
  1257. end;
  1258. procedure tstringdef.write_rtti_data(rt:trttitype);
  1259. begin
  1260. case string_typ of
  1261. st_ansistring:
  1262. begin
  1263. rttiList.concat(Tai_const.Create_8bit(tkAString));
  1264. write_rtti_name;
  1265. end;
  1266. st_widestring:
  1267. begin
  1268. rttiList.concat(Tai_const.Create_8bit(tkWString));
  1269. write_rtti_name;
  1270. end;
  1271. st_longstring:
  1272. begin
  1273. rttiList.concat(Tai_const.Create_8bit(tkLString));
  1274. write_rtti_name;
  1275. end;
  1276. st_shortstring:
  1277. begin
  1278. rttiList.concat(Tai_const.Create_8bit(tkSString));
  1279. write_rtti_name;
  1280. rttiList.concat(Tai_const.Create_8bit(len));
  1281. end;
  1282. end;
  1283. end;
  1284. function tstringdef.getmangledparaname : string;
  1285. begin
  1286. getmangledparaname:='STRING';
  1287. end;
  1288. function tstringdef.is_publishable : boolean;
  1289. begin
  1290. is_publishable:=true;
  1291. end;
  1292. {****************************************************************************
  1293. TENUMDEF
  1294. ****************************************************************************}
  1295. constructor tenumdef.create;
  1296. begin
  1297. inherited create;
  1298. deftype:=enumdef;
  1299. minval:=0;
  1300. maxval:=0;
  1301. calcsavesize;
  1302. has_jumps:=false;
  1303. basedef:=nil;
  1304. firstenum:=nil;
  1305. correct_owner_symtable;
  1306. end;
  1307. constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:longint);
  1308. begin
  1309. inherited create;
  1310. deftype:=enumdef;
  1311. minval:=_min;
  1312. maxval:=_max;
  1313. basedef:=_basedef;
  1314. calcsavesize;
  1315. has_jumps:=false;
  1316. firstenum:=basedef.firstenum;
  1317. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1318. firstenum:=tenumsym(firstenum).nextenum;
  1319. correct_owner_symtable;
  1320. end;
  1321. constructor tenumdef.ppuload(ppufile:tcompilerppufile);
  1322. begin
  1323. inherited ppuloaddef(ppufile);
  1324. deftype:=enumdef;
  1325. basedef:=tenumdef(ppufile.getderef);
  1326. minval:=ppufile.getlongint;
  1327. maxval:=ppufile.getlongint;
  1328. savesize:=ppufile.getlongint;
  1329. has_jumps:=false;
  1330. firstenum:=Nil;
  1331. end;
  1332. procedure tenumdef.calcsavesize;
  1333. begin
  1334. if (aktpackenum=4) or (min<0) or (max>65535) then
  1335. savesize:=4
  1336. else
  1337. if (aktpackenum=2) or (min<0) or (max>255) then
  1338. savesize:=2
  1339. else
  1340. savesize:=1;
  1341. end;
  1342. procedure tenumdef.setmax(_max:longint);
  1343. begin
  1344. maxval:=_max;
  1345. calcsavesize;
  1346. end;
  1347. procedure tenumdef.setmin(_min:longint);
  1348. begin
  1349. minval:=_min;
  1350. calcsavesize;
  1351. end;
  1352. function tenumdef.min:longint;
  1353. begin
  1354. min:=minval;
  1355. end;
  1356. function tenumdef.max:longint;
  1357. begin
  1358. max:=maxval;
  1359. end;
  1360. procedure tenumdef.deref;
  1361. begin
  1362. inherited deref;
  1363. resolvedef(pointer(basedef));
  1364. end;
  1365. destructor tenumdef.destroy;
  1366. begin
  1367. inherited destroy;
  1368. end;
  1369. procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
  1370. begin
  1371. inherited ppuwritedef(ppufile);
  1372. ppufile.putderef(basedef);
  1373. ppufile.putlongint(min);
  1374. ppufile.putlongint(max);
  1375. ppufile.putlongint(savesize);
  1376. ppufile.writeentry(ibenumdef);
  1377. end;
  1378. { used for enumdef because the symbols are
  1379. inserted in the owner symtable }
  1380. procedure tenumdef.correct_owner_symtable;
  1381. var
  1382. st : tsymtable;
  1383. begin
  1384. if assigned(owner) and
  1385. (owner.symtabletype in [recordsymtable,objectsymtable]) then
  1386. begin
  1387. owner.defindex.deleteindex(self);
  1388. st:=owner;
  1389. while (st.symtabletype in [recordsymtable,objectsymtable]) do
  1390. st:=st.next;
  1391. st.registerdef(self);
  1392. end;
  1393. end;
  1394. {$ifdef GDB}
  1395. function tenumdef.stabstring : pchar;
  1396. var st,st2 : pchar;
  1397. p : tenumsym;
  1398. s : string;
  1399. memsize : word;
  1400. begin
  1401. memsize := memsizeinc;
  1402. getmem(st,memsize);
  1403. { we can specify the size with @s<size>; prefix PM }
  1404. if savesize <> std_param_align then
  1405. strpcopy(st,'@s'+tostr(savesize*8)+';e')
  1406. else
  1407. strpcopy(st,'e');
  1408. p := tenumsym(firstenum);
  1409. while assigned(p) do
  1410. begin
  1411. s :=p.name+':'+tostr(p.value)+',';
  1412. { place for the ending ';' also }
  1413. if (strlen(st)+length(s)+1<memsize) then
  1414. strpcopy(strend(st),s)
  1415. else
  1416. begin
  1417. getmem(st2,memsize+memsizeinc);
  1418. strcopy(st2,st);
  1419. freemem(st,memsize);
  1420. st := st2;
  1421. memsize := memsize+memsizeinc;
  1422. strpcopy(strend(st),s);
  1423. end;
  1424. p := p.nextenum;
  1425. end;
  1426. strpcopy(strend(st),';');
  1427. stabstring := strnew(st);
  1428. freemem(st,memsize);
  1429. end;
  1430. {$endif GDB}
  1431. procedure tenumdef.write_child_rtti_data(rt:trttitype);
  1432. begin
  1433. if assigned(basedef) then
  1434. basedef.get_rtti_label(rt);
  1435. end;
  1436. procedure tenumdef.write_rtti_data(rt:trttitype);
  1437. var
  1438. hp : tenumsym;
  1439. begin
  1440. rttiList.concat(Tai_const.Create_8bit(tkEnumeration));
  1441. write_rtti_name;
  1442. case savesize of
  1443. 1:
  1444. rttiList.concat(Tai_const.Create_8bit(otUByte));
  1445. 2:
  1446. rttiList.concat(Tai_const.Create_8bit(otUWord));
  1447. 4:
  1448. rttiList.concat(Tai_const.Create_8bit(otULong));
  1449. end;
  1450. rttiList.concat(Tai_const.Create_32bit(min));
  1451. rttiList.concat(Tai_const.Create_32bit(max));
  1452. if assigned(basedef) then
  1453. rttiList.concat(Tai_const_symbol.Create(basedef.get_rtti_label(rt)))
  1454. else
  1455. rttiList.concat(Tai_const.Create_32bit(0));
  1456. hp:=tenumsym(firstenum);
  1457. while assigned(hp) do
  1458. begin
  1459. rttiList.concat(Tai_const.Create_8bit(length(hp.name)));
  1460. rttiList.concat(Tai_string.Create(lower(hp.name)));
  1461. hp:=hp.nextenum;
  1462. end;
  1463. rttiList.concat(Tai_const.Create_8bit(0));
  1464. end;
  1465. function tenumdef.is_publishable : boolean;
  1466. begin
  1467. is_publishable:=true;
  1468. end;
  1469. function tenumdef.gettypename : string;
  1470. begin
  1471. gettypename:='<enumeration type>';
  1472. end;
  1473. {****************************************************************************
  1474. TORDDEF
  1475. ****************************************************************************}
  1476. constructor torddef.create(t : tbasetype;v,b : TConstExprInt);
  1477. begin
  1478. inherited create;
  1479. deftype:=orddef;
  1480. low:=v;
  1481. high:=b;
  1482. typ:=t;
  1483. setsize;
  1484. end;
  1485. constructor torddef.ppuload(ppufile:tcompilerppufile);
  1486. var
  1487. l1,l2 : longint;
  1488. begin
  1489. inherited ppuloaddef(ppufile);
  1490. deftype:=orddef;
  1491. typ:=tbasetype(ppufile.getbyte);
  1492. if sizeof(TConstExprInt)=8 then
  1493. begin
  1494. l1:=ppufile.getlongint;
  1495. l2:=ppufile.getlongint;
  1496. {$ifopt R+}
  1497. {$define Range_check_on}
  1498. {$endif opt R+}
  1499. {$R- needed here }
  1500. low:=qword(l1)+(int64(l2) shl 32);
  1501. {$ifdef Range_check_on}
  1502. {$R+}
  1503. {$undef Range_check_on}
  1504. {$endif Range_check_on}
  1505. end
  1506. else
  1507. low:=ppufile.getlongint;
  1508. if sizeof(TConstExprInt)=8 then
  1509. begin
  1510. l1:=ppufile.getlongint;
  1511. l2:=ppufile.getlongint;
  1512. {$ifopt R+}
  1513. {$define Range_check_on}
  1514. {$endif opt R+}
  1515. {$R- needed here }
  1516. high:=qword(l1)+(int64(l2) shl 32);
  1517. {$ifdef Range_check_on}
  1518. {$R+}
  1519. {$undef Range_check_on}
  1520. {$endif Range_check_on}
  1521. end
  1522. else
  1523. high:=ppufile.getlongint;
  1524. setsize;
  1525. end;
  1526. function torddef.getcopy : tstoreddef;
  1527. begin
  1528. result:=torddef.create(typ,low,high);
  1529. result.deftype:=orddef;
  1530. torddef(result).low:=low;
  1531. torddef(result).high:=high;
  1532. torddef(result).typ:=typ;
  1533. torddef(result).savesize:=savesize;
  1534. end;
  1535. procedure torddef.setsize;
  1536. begin
  1537. case typ of
  1538. u8bit,s8bit,
  1539. uchar,bool8bit:
  1540. savesize:=1;
  1541. u16bit,s16bit,
  1542. bool16bit,uwidechar:
  1543. savesize:=2;
  1544. s32bit,u32bit,
  1545. bool32bit:
  1546. savesize:=4;
  1547. u64bit,s64bit:
  1548. savesize:=8;
  1549. else
  1550. savesize:=0;
  1551. end;
  1552. end;
  1553. procedure torddef.ppuwrite(ppufile:tcompilerppufile);
  1554. begin
  1555. inherited ppuwritedef(ppufile);
  1556. ppufile.putbyte(byte(typ));
  1557. if sizeof(TConstExprInt)=8 then
  1558. begin
  1559. ppufile.putlongint(longint(lo(low)));
  1560. ppufile.putlongint(longint(hi(low)));
  1561. end
  1562. else
  1563. ppufile.putlongint(low);
  1564. if sizeof(TConstExprInt)=8 then
  1565. begin
  1566. ppufile.putlongint(longint(lo(high)));
  1567. ppufile.putlongint(longint(hi(high)));
  1568. end
  1569. else
  1570. ppufile.putlongint(high);
  1571. ppufile.writeentry(iborddef);
  1572. end;
  1573. {$ifdef GDB}
  1574. function torddef.stabstring : pchar;
  1575. begin
  1576. case typ of
  1577. uvoid : stabstring := strpnew(numberstring+';');
  1578. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  1579. {$ifdef Use_integer_types_for_boolean}
  1580. bool8bit,
  1581. bool16bit,
  1582. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  1583. {$else : not Use_integer_types_for_boolean}
  1584. uchar : stabstring := strpnew('-20;');
  1585. uwidechar : stabstring := strpnew('-30;');
  1586. bool8bit : stabstring := strpnew('-21;');
  1587. bool16bit : stabstring := strpnew('-22;');
  1588. bool32bit : stabstring := strpnew('-23;');
  1589. u64bit : stabstring := strpnew('-32;');
  1590. s64bit : stabstring := strpnew('-31;');
  1591. {$endif not Use_integer_types_for_boolean}
  1592. {u32bit : stabstring := tstoreddef(s32bittype.def).numberstring+';0;-1;'); }
  1593. else
  1594. stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';'+tostr(longint(low))+';'+tostr(longint(high))+';');
  1595. end;
  1596. end;
  1597. {$endif GDB}
  1598. procedure torddef.write_rtti_data(rt:trttitype);
  1599. procedure dointeger;
  1600. const
  1601. trans : array[tbasetype] of byte =
  1602. (otUByte{otNone},
  1603. otUByte,otUWord,otULong,otUByte{otNone},
  1604. otSByte,otSWord,otSLong,otUByte{otNone},
  1605. otUByte,otUWord,otULong,
  1606. otUByte,otUWord);
  1607. begin
  1608. write_rtti_name;
  1609. rttiList.concat(Tai_const.Create_8bit(byte(trans[typ])));
  1610. rttiList.concat(Tai_const.Create_32bit(longint(low)));
  1611. rttiList.concat(Tai_const.Create_32bit(longint(high)));
  1612. end;
  1613. begin
  1614. case typ of
  1615. s64bit :
  1616. begin
  1617. rttiList.concat(Tai_const.Create_8bit(tkInt64));
  1618. write_rtti_name;
  1619. if target_info.endian=endian_little then
  1620. begin
  1621. { low }
  1622. rttiList.concat(Tai_const.Create_32bit($0));
  1623. rttiList.concat(Tai_const.Create_32bit(longint($80000000)));
  1624. { high }
  1625. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1626. rttiList.concat(Tai_const.Create_32bit($7fffffff));
  1627. end
  1628. else
  1629. begin
  1630. { low }
  1631. rttiList.concat(Tai_const.Create_32bit(longint($80000000)));
  1632. rttiList.concat(Tai_const.Create_32bit($0));
  1633. { high }
  1634. rttiList.concat(Tai_const.Create_32bit($7fffffff));
  1635. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1636. end;
  1637. end;
  1638. u64bit :
  1639. begin
  1640. rttiList.concat(Tai_const.Create_8bit(tkQWord));
  1641. write_rtti_name;
  1642. { low }
  1643. rttiList.concat(Tai_const.Create_32bit($0));
  1644. rttiList.concat(Tai_const.Create_32bit($0));
  1645. { high }
  1646. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1647. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1648. end;
  1649. bool8bit:
  1650. begin
  1651. rttiList.concat(Tai_const.Create_8bit(tkBool));
  1652. dointeger;
  1653. end;
  1654. uchar:
  1655. begin
  1656. rttiList.concat(Tai_const.Create_8bit(tkChar));
  1657. dointeger;
  1658. end;
  1659. uwidechar:
  1660. begin
  1661. rttiList.concat(Tai_const.Create_8bit(tkWChar));
  1662. dointeger;
  1663. end;
  1664. else
  1665. begin
  1666. rttiList.concat(Tai_const.Create_8bit(tkInteger));
  1667. dointeger;
  1668. end;
  1669. end;
  1670. end;
  1671. function torddef.is_publishable : boolean;
  1672. begin
  1673. is_publishable:=(typ<>uvoid);
  1674. end;
  1675. function torddef.gettypename : string;
  1676. const
  1677. names : array[tbasetype] of string[20] = (
  1678. 'untyped',
  1679. 'Byte','Word','DWord','QWord',
  1680. 'ShortInt','SmallInt','LongInt','Int64',
  1681. 'Boolean','WordBool','LongBool',
  1682. 'Char','WideChar');
  1683. begin
  1684. gettypename:=names[typ];
  1685. end;
  1686. {****************************************************************************
  1687. TFLOATDEF
  1688. ****************************************************************************}
  1689. constructor tfloatdef.create(t : tfloattype);
  1690. begin
  1691. inherited create;
  1692. deftype:=floatdef;
  1693. typ:=t;
  1694. setsize;
  1695. end;
  1696. constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
  1697. begin
  1698. inherited ppuloaddef(ppufile);
  1699. deftype:=floatdef;
  1700. typ:=tfloattype(ppufile.getbyte);
  1701. setsize;
  1702. end;
  1703. function tfloatdef.getcopy : tstoreddef;
  1704. begin
  1705. result:=tfloatdef.create(typ);
  1706. result.deftype:=floatdef;
  1707. tfloatdef(result).savesize:=savesize;
  1708. end;
  1709. procedure tfloatdef.setsize;
  1710. begin
  1711. case typ of
  1712. s32real : savesize:=4;
  1713. s80real : savesize:=extended_size;
  1714. s64real,
  1715. s64currency,
  1716. s64comp : savesize:=8;
  1717. else
  1718. savesize:=0;
  1719. end;
  1720. end;
  1721. procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
  1722. begin
  1723. inherited ppuwritedef(ppufile);
  1724. ppufile.putbyte(byte(typ));
  1725. ppufile.writeentry(ibfloatdef);
  1726. end;
  1727. {$ifdef GDB}
  1728. function tfloatdef.stabstring : pchar;
  1729. begin
  1730. case typ of
  1731. s32real,
  1732. s64real : stabstring := strpnew('r'+
  1733. tstoreddef(s32bittype.def).numberstring+';'+tostr(savesize)+';0;');
  1734. { found this solution in stabsread.c from GDB v4.16 }
  1735. s64currency,
  1736. s64comp : stabstring := strpnew('r'+
  1737. tstoreddef(s32bittype.def).numberstring+';-'+tostr(savesize)+';0;');
  1738. { under dos at least you must give a size of twelve instead of 10 !! }
  1739. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1740. s80real : stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';12;0;');
  1741. else
  1742. internalerror(10005);
  1743. end;
  1744. end;
  1745. {$endif GDB}
  1746. procedure tfloatdef.write_rtti_data(rt:trttitype);
  1747. const
  1748. {tfloattype = (s32real,s64real,s80real,s64bit,s128bit);}
  1749. translate : array[tfloattype] of byte =
  1750. (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,ftFloat128);
  1751. begin
  1752. rttiList.concat(Tai_const.Create_8bit(tkFloat));
  1753. write_rtti_name;
  1754. rttiList.concat(Tai_const.Create_8bit(translate[typ]));
  1755. end;
  1756. function tfloatdef.is_publishable : boolean;
  1757. begin
  1758. is_publishable:=true;
  1759. end;
  1760. function tfloatdef.gettypename : string;
  1761. const
  1762. names : array[tfloattype] of string[20] = (
  1763. 'Single','Double','Extended','Comp','Currency','Float128');
  1764. begin
  1765. gettypename:=names[typ];
  1766. end;
  1767. {****************************************************************************
  1768. TFILEDEF
  1769. ****************************************************************************}
  1770. constructor tfiledef.createtext;
  1771. begin
  1772. inherited create;
  1773. deftype:=filedef;
  1774. filetyp:=ft_text;
  1775. typedfiletype.reset;
  1776. setsize;
  1777. end;
  1778. constructor tfiledef.createuntyped;
  1779. begin
  1780. inherited create;
  1781. deftype:=filedef;
  1782. filetyp:=ft_untyped;
  1783. typedfiletype.reset;
  1784. setsize;
  1785. end;
  1786. constructor tfiledef.createtyped(const tt : ttype);
  1787. begin
  1788. inherited create;
  1789. deftype:=filedef;
  1790. filetyp:=ft_typed;
  1791. typedfiletype:=tt;
  1792. setsize;
  1793. end;
  1794. constructor tfiledef.ppuload(ppufile:tcompilerppufile);
  1795. begin
  1796. inherited ppuloaddef(ppufile);
  1797. deftype:=filedef;
  1798. filetyp:=tfiletyp(ppufile.getbyte);
  1799. if filetyp=ft_typed then
  1800. ppufile.gettype(typedfiletype)
  1801. else
  1802. typedfiletype.reset;
  1803. setsize;
  1804. end;
  1805. procedure tfiledef.deref;
  1806. begin
  1807. inherited deref;
  1808. if filetyp=ft_typed then
  1809. typedfiletype.resolve;
  1810. end;
  1811. procedure tfiledef.setsize;
  1812. begin
  1813. case filetyp of
  1814. ft_text :
  1815. savesize:=572;
  1816. ft_typed,
  1817. ft_untyped :
  1818. savesize:=316;
  1819. end;
  1820. end;
  1821. procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
  1822. begin
  1823. inherited ppuwritedef(ppufile);
  1824. ppufile.putbyte(byte(filetyp));
  1825. if filetyp=ft_typed then
  1826. ppufile.puttype(typedfiletype);
  1827. ppufile.writeentry(ibfiledef);
  1828. end;
  1829. {$ifdef GDB}
  1830. function tfiledef.stabstring : pchar;
  1831. begin
  1832. {$IfDef GDBknowsfiles}
  1833. case filetyp of
  1834. ft_typed :
  1835. stabstring := strpnew('d'+typedfiletype.def.numberstring{+';'});
  1836. ft_untyped :
  1837. stabstring := strpnew('d'+voiddef.numberstring{+';'});
  1838. ft_text :
  1839. stabstring := strpnew('d'+cchartype^.numberstring{+';'});
  1840. end;
  1841. {$Else}
  1842. {based on
  1843. FileRec = Packed Record
  1844. Handle,
  1845. Mode,
  1846. RecSize : longint;
  1847. _private : array[1..32] of byte;
  1848. UserData : array[1..16] of byte;
  1849. name : array[0..255] of char;
  1850. End; }
  1851. { the buffer part is still missing !! (PM) }
  1852. { but the string could become too long !! }
  1853. stabstring := strpnew('s'+tostr(savesize)+
  1854. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1855. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1856. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1857. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1858. +',96,256;'+
  1859. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1860. +',352,128;'+
  1861. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1862. +',480,2048;;');
  1863. {$EndIf}
  1864. end;
  1865. procedure tfiledef.concatstabto(asmlist : taasmoutput);
  1866. begin
  1867. { most file defs are unnamed !!! }
  1868. if ((typesym = nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1869. (is_def_stab_written = not_written) then
  1870. begin
  1871. if assigned(typedfiletype.def) then
  1872. forcestabto(asmlist,typedfiletype.def);
  1873. inherited concatstabto(asmlist);
  1874. end;
  1875. end;
  1876. {$endif GDB}
  1877. function tfiledef.gettypename : string;
  1878. begin
  1879. case filetyp of
  1880. ft_untyped:
  1881. gettypename:='File';
  1882. ft_typed:
  1883. gettypename:='File Of '+typedfiletype.def.typename;
  1884. ft_text:
  1885. gettypename:='Text'
  1886. end;
  1887. end;
  1888. function tfiledef.getmangledparaname : string;
  1889. begin
  1890. case filetyp of
  1891. ft_untyped:
  1892. getmangledparaname:='FILE';
  1893. ft_typed:
  1894. getmangledparaname:='FILE$OF$'+typedfiletype.def.mangledparaname;
  1895. ft_text:
  1896. getmangledparaname:='TEXT'
  1897. end;
  1898. end;
  1899. {****************************************************************************
  1900. TVARIANTDEF
  1901. ****************************************************************************}
  1902. constructor tvariantdef.create;
  1903. begin
  1904. inherited create;
  1905. deftype:=variantdef;
  1906. setsize;
  1907. end;
  1908. constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
  1909. begin
  1910. inherited ppuloaddef(ppufile);
  1911. deftype:=variantdef;
  1912. setsize;
  1913. end;
  1914. procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
  1915. begin
  1916. inherited ppuwritedef(ppufile);
  1917. ppufile.writeentry(ibvariantdef);
  1918. end;
  1919. procedure tvariantdef.setsize;
  1920. begin
  1921. savesize:=16;
  1922. end;
  1923. function tvariantdef.gettypename : string;
  1924. begin
  1925. gettypename:='Variant';
  1926. end;
  1927. procedure tvariantdef.write_rtti_data(rt:trttitype);
  1928. begin
  1929. rttiList.concat(Tai_const.Create_8bit(tkVariant));
  1930. end;
  1931. function tvariantdef.needs_inittable : boolean;
  1932. begin
  1933. needs_inittable:=true;
  1934. end;
  1935. {$ifdef GDB}
  1936. procedure tvariantdef.concatstabto(asmlist : taasmoutput);
  1937. begin
  1938. { don't know how to handle this }
  1939. end;
  1940. {$endif GDB}
  1941. {****************************************************************************
  1942. TPOINTERDEF
  1943. ****************************************************************************}
  1944. constructor tpointerdef.create(const tt : ttype);
  1945. begin
  1946. inherited create;
  1947. deftype:=pointerdef;
  1948. pointertype:=tt;
  1949. is_far:=false;
  1950. savesize:=POINTER_SIZE;
  1951. end;
  1952. constructor tpointerdef.createfar(const tt : ttype);
  1953. begin
  1954. inherited create;
  1955. deftype:=pointerdef;
  1956. pointertype:=tt;
  1957. is_far:=true;
  1958. savesize:=POINTER_SIZE;
  1959. end;
  1960. constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
  1961. begin
  1962. inherited ppuloaddef(ppufile);
  1963. deftype:=pointerdef;
  1964. ppufile.gettype(pointertype);
  1965. is_far:=(ppufile.getbyte<>0);
  1966. savesize:=POINTER_SIZE;
  1967. end;
  1968. procedure tpointerdef.deref;
  1969. begin
  1970. inherited deref;
  1971. pointertype.resolve;
  1972. end;
  1973. procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
  1974. begin
  1975. inherited ppuwritedef(ppufile);
  1976. ppufile.puttype(pointertype);
  1977. ppufile.putbyte(byte(is_far));
  1978. ppufile.writeentry(ibpointerdef);
  1979. end;
  1980. {$ifdef GDB}
  1981. function tpointerdef.stabstring : pchar;
  1982. begin
  1983. stabstring := strpnew('*'+tstoreddef(pointertype.def).numberstring);
  1984. end;
  1985. procedure tpointerdef.concatstabto(asmlist : taasmoutput);
  1986. var st,nb : string;
  1987. sym_line_no : longint;
  1988. begin
  1989. if assigned(pointertype.def) and
  1990. (pointertype.def.deftype=forwarddef) then
  1991. exit;
  1992. if ( (typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1993. (is_def_stab_written = not_written) then
  1994. begin
  1995. is_def_stab_written := being_written;
  1996. if assigned(pointertype.def) and
  1997. (pointertype.def.deftype in [recorddef,objectdef]) then
  1998. begin
  1999. if pointertype.def.deftype=objectdef then
  2000. nb:=tobjectdef(pointertype.def).classnumberstring
  2001. else
  2002. nb:=tstoreddef(pointertype.def).numberstring;
  2003. {to avoid infinite recursion in record with next-like fields }
  2004. if tstoreddef(pointertype.def).is_def_stab_written = being_written then
  2005. begin
  2006. if assigned(pointertype.def.typesym) then
  2007. begin
  2008. if assigned(typesym) then
  2009. begin
  2010. st := ttypesym(typesym).name;
  2011. sym_line_no:=ttypesym(typesym).fileinfo.line;
  2012. end
  2013. else
  2014. begin
  2015. st := ' ';
  2016. sym_line_no:=0;
  2017. end;
  2018. st := '"'+st+':t'+numberstring+'=*'+nb
  2019. +'=xs'+pointertype.def.typesym.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  2020. asmList.concat(Tai_stabs.Create(strpnew(st)));
  2021. end;
  2022. end
  2023. else
  2024. begin
  2025. is_def_stab_written := not_written;
  2026. inherited concatstabto(asmlist);
  2027. end;
  2028. is_def_stab_written := written;
  2029. end
  2030. else
  2031. begin
  2032. if assigned(pointertype.def) then
  2033. forcestabto(asmlist,pointertype.def);
  2034. is_def_stab_written := not_written;
  2035. inherited concatstabto(asmlist);
  2036. end;
  2037. end;
  2038. end;
  2039. {$endif GDB}
  2040. function tpointerdef.gettypename : string;
  2041. begin
  2042. if is_far then
  2043. gettypename:='^'+pointertype.def.typename+';far'
  2044. else
  2045. gettypename:='^'+pointertype.def.typename;
  2046. end;
  2047. {****************************************************************************
  2048. TCLASSREFDEF
  2049. ****************************************************************************}
  2050. constructor tclassrefdef.create(const t:ttype);
  2051. begin
  2052. inherited create(t);
  2053. deftype:=classrefdef;
  2054. end;
  2055. constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
  2056. begin
  2057. { be careful, tclassdefref inherits from tpointerdef }
  2058. inherited ppuloaddef(ppufile);
  2059. deftype:=classrefdef;
  2060. ppufile.gettype(pointertype);
  2061. is_far:=false;
  2062. savesize:=POINTER_SIZE;
  2063. end;
  2064. procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
  2065. begin
  2066. { be careful, tclassdefref inherits from tpointerdef }
  2067. inherited ppuwritedef(ppufile);
  2068. ppufile.puttype(pointertype);
  2069. ppufile.writeentry(ibclassrefdef);
  2070. end;
  2071. {$ifdef GDB}
  2072. function tclassrefdef.stabstring : pchar;
  2073. begin
  2074. stabstring:=strpnew(tstoreddef(pvmttype.def).numberstring+';');
  2075. end;
  2076. procedure tclassrefdef.concatstabto(asmlist : taasmoutput);
  2077. begin
  2078. inherited concatstabto(asmlist);
  2079. end;
  2080. {$endif GDB}
  2081. function tclassrefdef.gettypename : string;
  2082. begin
  2083. gettypename:='Class Of '+pointertype.def.typename;
  2084. end;
  2085. {***************************************************************************
  2086. TSETDEF
  2087. ***************************************************************************}
  2088. constructor tsetdef.create(const t:ttype;high : longint);
  2089. begin
  2090. inherited create;
  2091. deftype:=setdef;
  2092. elementtype:=t;
  2093. if high<32 then
  2094. begin
  2095. settype:=smallset;
  2096. {$ifdef testvarsets}
  2097. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  2098. {$endif}
  2099. savesize:=Sizeof(longint)
  2100. {$ifdef testvarsets}
  2101. else {No, use $PACKSET VALUE for rounding}
  2102. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  2103. {$endif}
  2104. ;
  2105. end
  2106. else
  2107. if high<256 then
  2108. begin
  2109. settype:=normset;
  2110. savesize:=32;
  2111. end
  2112. else
  2113. {$ifdef testvarsets}
  2114. if high<$10000 then
  2115. begin
  2116. settype:=varset;
  2117. savesize:=4*((high+31) div 32);
  2118. end
  2119. else
  2120. {$endif testvarsets}
  2121. Message(sym_e_ill_type_decl_set);
  2122. end;
  2123. constructor tsetdef.ppuload(ppufile:tcompilerppufile);
  2124. begin
  2125. inherited ppuloaddef(ppufile);
  2126. deftype:=setdef;
  2127. ppufile.gettype(elementtype);
  2128. settype:=tsettype(ppufile.getbyte);
  2129. case settype of
  2130. normset : savesize:=32;
  2131. varset : savesize:=ppufile.getlongint;
  2132. smallset : savesize:=Sizeof(longint);
  2133. end;
  2134. end;
  2135. destructor tsetdef.destroy;
  2136. begin
  2137. inherited destroy;
  2138. end;
  2139. procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
  2140. begin
  2141. inherited ppuwritedef(ppufile);
  2142. ppufile.puttype(elementtype);
  2143. ppufile.putbyte(byte(settype));
  2144. if settype=varset then
  2145. ppufile.putlongint(savesize);
  2146. ppufile.writeentry(ibsetdef);
  2147. end;
  2148. procedure tsetdef.changesettype(s:tsettype);
  2149. begin
  2150. case s of
  2151. smallset :
  2152. savesize:=sizeof(longint);
  2153. normset :
  2154. savesize:=32;
  2155. varset :
  2156. internalerror(200110201);
  2157. end;
  2158. settype:=s;
  2159. end;
  2160. {$ifdef GDB}
  2161. function tsetdef.stabstring : pchar;
  2162. begin
  2163. { For small sets write a longint, which can at least be seen
  2164. in the current GDB's (PFV)
  2165. this is obsolete with GDBPAS !!
  2166. and anyhow creates problems with version 4.18!! PM
  2167. if settype=smallset then
  2168. stabstring := strpnew('r'+s32bittype^.numberstring+';0;0xffffffff;')
  2169. else }
  2170. stabstring := strpnew('@s'+tostr(savesize*8)+';S'+tstoreddef(elementtype.def).numberstring);
  2171. end;
  2172. procedure tsetdef.concatstabto(asmlist : taasmoutput);
  2173. begin
  2174. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2175. (is_def_stab_written = not_written) then
  2176. begin
  2177. if assigned(elementtype.def) then
  2178. forcestabto(asmlist,elementtype.def);
  2179. inherited concatstabto(asmlist);
  2180. end;
  2181. end;
  2182. {$endif GDB}
  2183. procedure tsetdef.deref;
  2184. begin
  2185. inherited deref;
  2186. elementtype.resolve;
  2187. end;
  2188. procedure tsetdef.write_child_rtti_data(rt:trttitype);
  2189. begin
  2190. tstoreddef(elementtype.def).get_rtti_label(rt);
  2191. end;
  2192. procedure tsetdef.write_rtti_data(rt:trttitype);
  2193. begin
  2194. rttiList.concat(Tai_const.Create_8bit(tkSet));
  2195. write_rtti_name;
  2196. rttiList.concat(Tai_const.Create_8bit(otULong));
  2197. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2198. end;
  2199. function tsetdef.is_publishable : boolean;
  2200. begin
  2201. is_publishable:=(settype=smallset);
  2202. end;
  2203. function tsetdef.gettypename : string;
  2204. begin
  2205. if assigned(elementtype.def) then
  2206. gettypename:='Set Of '+elementtype.def.typename
  2207. else
  2208. gettypename:='Empty Set';
  2209. end;
  2210. {***************************************************************************
  2211. TFORMALDEF
  2212. ***************************************************************************}
  2213. constructor tformaldef.create;
  2214. var
  2215. stregdef : boolean;
  2216. begin
  2217. stregdef:=registerdef;
  2218. registerdef:=false;
  2219. inherited create;
  2220. deftype:=formaldef;
  2221. registerdef:=stregdef;
  2222. { formaldef must be registered at unit level !! }
  2223. if registerdef and assigned(current_module) then
  2224. if assigned(current_module.localsymtable) then
  2225. tsymtable(current_module.localsymtable).registerdef(self)
  2226. else if assigned(current_module.globalsymtable) then
  2227. tsymtable(current_module.globalsymtable).registerdef(self);
  2228. savesize:=POINTER_SIZE;
  2229. end;
  2230. constructor tformaldef.ppuload(ppufile:tcompilerppufile);
  2231. begin
  2232. inherited ppuloaddef(ppufile);
  2233. deftype:=formaldef;
  2234. savesize:=POINTER_SIZE;
  2235. end;
  2236. procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
  2237. begin
  2238. inherited ppuwritedef(ppufile);
  2239. ppufile.writeentry(ibformaldef);
  2240. end;
  2241. {$ifdef GDB}
  2242. function tformaldef.stabstring : pchar;
  2243. begin
  2244. stabstring := strpnew('formal'+numberstring+';');
  2245. end;
  2246. procedure tformaldef.concatstabto(asmlist : taasmoutput);
  2247. begin
  2248. { formaldef can't be stab'ed !}
  2249. end;
  2250. {$endif GDB}
  2251. function tformaldef.gettypename : string;
  2252. begin
  2253. gettypename:='<Formal type>';
  2254. end;
  2255. {***************************************************************************
  2256. TARRAYDEF
  2257. ***************************************************************************}
  2258. constructor tarraydef.create(l,h : longint;const t : ttype);
  2259. begin
  2260. inherited create;
  2261. deftype:=arraydef;
  2262. lowrange:=l;
  2263. highrange:=h;
  2264. rangetype:=t;
  2265. elementtype.reset;
  2266. IsVariant:=false;
  2267. IsConstructor:=false;
  2268. IsArrayOfConst:=false;
  2269. IsDynamicArray:=false;
  2270. end;
  2271. constructor tarraydef.ppuload(ppufile:tcompilerppufile);
  2272. begin
  2273. inherited ppuloaddef(ppufile);
  2274. deftype:=arraydef;
  2275. { the addresses are calculated later }
  2276. ppufile.gettype(_elementtype);
  2277. ppufile.gettype(rangetype);
  2278. lowrange:=ppufile.getlongint;
  2279. highrange:=ppufile.getlongint;
  2280. IsArrayOfConst:=boolean(ppufile.getbyte);
  2281. IsDynamicArray:=boolean(ppufile.getbyte);
  2282. IsVariant:=false;
  2283. IsConstructor:=false;
  2284. end;
  2285. procedure tarraydef.deref;
  2286. begin
  2287. inherited deref;
  2288. _elementtype.resolve;
  2289. rangetype.resolve;
  2290. end;
  2291. procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
  2292. begin
  2293. inherited ppuwritedef(ppufile);
  2294. ppufile.puttype(_elementtype);
  2295. ppufile.puttype(rangetype);
  2296. ppufile.putlongint(lowrange);
  2297. ppufile.putlongint(highrange);
  2298. ppufile.putbyte(byte(IsArrayOfConst));
  2299. ppufile.putbyte(byte(IsDynamicArray));
  2300. ppufile.writeentry(ibarraydef);
  2301. end;
  2302. {$ifdef GDB}
  2303. function tarraydef.stabstring : pchar;
  2304. begin
  2305. stabstring := strpnew('ar'+tstoreddef(rangetype.def).numberstring+';'
  2306. +tostr(lowrange)+';'+tostr(highrange)+';'+tstoreddef(_elementtype.def).numberstring);
  2307. end;
  2308. procedure tarraydef.concatstabto(asmlist : taasmoutput);
  2309. begin
  2310. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2311. and (is_def_stab_written = not_written) then
  2312. begin
  2313. {when array are inserted they have no definition yet !!}
  2314. if assigned(_elementtype.def) then
  2315. inherited concatstabto(asmlist);
  2316. end;
  2317. end;
  2318. {$endif GDB}
  2319. function tarraydef.elesize : longint;
  2320. begin
  2321. elesize:=_elementtype.def.size;
  2322. end;
  2323. function tarraydef.size : longint;
  2324. var
  2325. _resultsize,
  2326. newsize,
  2327. cachedsize: TConstExprInt;
  2328. begin
  2329. if IsDynamicArray then
  2330. begin
  2331. size:=POINTER_SIZE;
  2332. exit;
  2333. end;
  2334. cachedsize := elesize;
  2335. {Tarraydef.size may never be called for an open array!}
  2336. if highrange<lowrange then
  2337. internalerror(99080501);
  2338. newsize:=(int64(highrange)-int64(lowrange)+1)*cachedsize;
  2339. if (cachedsize>0) and
  2340. (
  2341. (TConstExprInt(highrange)-TConstExprInt(lowrange) > $7fffffff) or
  2342. { () are needed around elesize-1 to avoid a possible
  2343. integer overflow for elesize=1 !! PM }
  2344. (($7fffffff div cachedsize + (cachedsize -1)) < (int64(highrange) - int64(lowrange)))
  2345. ) Then
  2346. begin
  2347. Message(sym_e_segment_too_large);
  2348. _resultsize := 4
  2349. end
  2350. else
  2351. begin
  2352. { prevent an overflow }
  2353. if newsize>high(longint) then
  2354. _resultsize:=high(longint)
  2355. else
  2356. _resultsize:=newsize;
  2357. end;
  2358. size := _resultsize;
  2359. end;
  2360. procedure tarraydef.setelementtype(t: ttype);
  2361. begin
  2362. _elementtype:=t;
  2363. If IsDynamicArray then
  2364. exit;
  2365. if (TConstExprInt(highrange)-TConstExprInt(lowrange) > $7fffffff) then
  2366. Message(sym_e_segment_too_large);
  2367. end;
  2368. function tarraydef.alignment : longint;
  2369. begin
  2370. { alignment is the size of the elements }
  2371. if elementtype.def.deftype=recorddef then
  2372. alignment:=elementtype.def.alignment
  2373. else
  2374. alignment:=elesize;
  2375. end;
  2376. function tarraydef.needs_inittable : boolean;
  2377. begin
  2378. needs_inittable:=IsDynamicArray or elementtype.def.needs_inittable;
  2379. end;
  2380. procedure tarraydef.write_child_rtti_data(rt:trttitype);
  2381. begin
  2382. tstoreddef(elementtype.def).get_rtti_label(rt);
  2383. end;
  2384. procedure tarraydef.write_rtti_data(rt:trttitype);
  2385. begin
  2386. if IsDynamicArray then
  2387. rttiList.concat(Tai_const.Create_8bit(tkdynarray))
  2388. else
  2389. rttiList.concat(Tai_const.Create_8bit(tkarray));
  2390. write_rtti_name;
  2391. { size of elements }
  2392. rttiList.concat(Tai_const.Create_32bit(elesize));
  2393. { count of elements }
  2394. if not(IsDynamicArray) then
  2395. rttiList.concat(Tai_const.Create_32bit(highrange-lowrange+1));
  2396. { element type }
  2397. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2398. { variant type }
  2399. // !!!!!!!!!!!!!!!!
  2400. end;
  2401. function tarraydef.gettypename : string;
  2402. begin
  2403. if isarrayofconst or isConstructor then
  2404. begin
  2405. if isvariant or ((highrange=-1) and (lowrange=0)) then
  2406. gettypename:='Array Of Const'
  2407. else
  2408. gettypename:='Array Of '+elementtype.def.typename;
  2409. end
  2410. else if ((highrange=-1) and (lowrange=0)) or IsDynamicArray then
  2411. gettypename:='Array Of '+elementtype.def.typename
  2412. else
  2413. begin
  2414. if rangetype.def.deftype=enumdef then
  2415. gettypename:='Array['+rangetype.def.typename+'] Of '+elementtype.def.typename
  2416. else
  2417. gettypename:='Array['+tostr(lowrange)+'..'+
  2418. tostr(highrange)+'] Of '+elementtype.def.typename
  2419. end;
  2420. end;
  2421. function tarraydef.getmangledparaname : string;
  2422. begin
  2423. if isarrayofconst then
  2424. getmangledparaname:='array_of_const'
  2425. else
  2426. if ((highrange=-1) and (lowrange=0)) then
  2427. getmangledparaname:='array_of_'+elementtype.def.mangledparaname
  2428. else
  2429. internalerror(200204176);
  2430. end;
  2431. {***************************************************************************
  2432. tabstractrecorddef
  2433. ***************************************************************************}
  2434. function tabstractrecorddef.getsymtable(t:tgetsymtable):tsymtable;
  2435. begin
  2436. if t=gs_record then
  2437. getsymtable:=symtable
  2438. else
  2439. getsymtable:=nil;
  2440. end;
  2441. {$ifdef GDB}
  2442. procedure tabstractrecorddef.addname(p : tnamedindexitem;arg:pointer);
  2443. var
  2444. news, newrec : pchar;
  2445. spec : string[3];
  2446. varsize : longint;
  2447. begin
  2448. { static variables from objects are like global objects }
  2449. if (sp_static in tsym(p).symoptions) then
  2450. exit;
  2451. If tsym(p).typ = varsym then
  2452. begin
  2453. if (sp_protected in tsym(p).symoptions) then
  2454. spec:='/1'
  2455. else if (sp_private in tsym(p).symoptions) then
  2456. spec:='/0'
  2457. else
  2458. spec:='';
  2459. if not assigned(tvarsym(p).vartype.def) then
  2460. writeln(tvarsym(p).name);
  2461. { class fields are pointers PM, obsolete now PM }
  2462. {if (tvarsym(p).vartype.def.deftype=objectdef) and
  2463. tobjectdef(tvarsym(p).vartype.def).is_class then
  2464. spec:=spec+'*'; }
  2465. varsize:=tvarsym(p).vartype.def.size;
  2466. { open arrays made overflows !! }
  2467. if varsize>$fffffff then
  2468. varsize:=$fffffff;
  2469. newrec := strpnew(p.name+':'+spec+tstoreddef(tvarsym(p).vartype.def).numberstring
  2470. +','+tostr(tvarsym(p).address*8)+','
  2471. +tostr(varsize*8)+';');
  2472. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2473. begin
  2474. getmem(news,stabrecsize+memsizeinc);
  2475. strcopy(news,stabrecstring);
  2476. freemem(stabrecstring,stabrecsize);
  2477. stabrecsize:=stabrecsize+memsizeinc;
  2478. stabrecstring:=news;
  2479. end;
  2480. strcat(StabRecstring,newrec);
  2481. strdispose(newrec);
  2482. {This should be used for case !!}
  2483. inc(RecOffset,tvarsym(p).vartype.def.size);
  2484. end;
  2485. end;
  2486. {$endif GDB}
  2487. procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem;arg:pointer);
  2488. begin
  2489. if (FRTTIType=fullrtti) or
  2490. ((tsym(sym).typ=varsym) and
  2491. tvarsym(sym).vartype.def.needs_inittable) then
  2492. inc(Count);
  2493. end;
  2494. procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem;arg:pointer);
  2495. begin
  2496. if (FRTTIType=fullrtti) or
  2497. ((tsym(sym).typ=varsym) and
  2498. tvarsym(sym).vartype.def.needs_inittable) then
  2499. tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType);
  2500. end;
  2501. procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem;arg:pointer);
  2502. begin
  2503. if (FRTTIType=fullrtti) or
  2504. ((tsym(sym).typ=varsym) and
  2505. tvarsym(sym).vartype.def.needs_inittable) then
  2506. begin
  2507. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType)));
  2508. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  2509. end;
  2510. end;
  2511. {***************************************************************************
  2512. trecorddef
  2513. ***************************************************************************}
  2514. constructor trecorddef.create(p : tsymtable);
  2515. begin
  2516. inherited create;
  2517. deftype:=recorddef;
  2518. symtable:=p;
  2519. symtable.defowner:=self;
  2520. { recordalign -1 means C record packing, that starts
  2521. with an alignment of 1 }
  2522. if aktalignment.recordalignmax=-1 then
  2523. symtable.dataalignment:=1
  2524. else
  2525. symtable.dataalignment:=aktalignment.recordalignmax;
  2526. isunion:=false;
  2527. end;
  2528. constructor trecorddef.ppuload(ppufile:tcompilerppufile);
  2529. var
  2530. oldread_member : boolean;
  2531. begin
  2532. inherited ppuloaddef(ppufile);
  2533. deftype:=recorddef;
  2534. savesize:=ppufile.getlongint;
  2535. oldread_member:=read_member;
  2536. read_member:=true;
  2537. symtable:=trecordsymtable.create;
  2538. trecordsymtable(symtable).ppuload(ppufile);
  2539. read_member:=oldread_member;
  2540. symtable.defowner:=self;
  2541. isunion:=false;
  2542. end;
  2543. destructor trecorddef.destroy;
  2544. begin
  2545. if assigned(symtable) then
  2546. symtable.free;
  2547. inherited destroy;
  2548. end;
  2549. function trecorddef.needs_inittable : boolean;
  2550. begin
  2551. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2552. end;
  2553. procedure trecorddef.deref;
  2554. var
  2555. oldrecsyms : tsymtable;
  2556. begin
  2557. inherited deref;
  2558. oldrecsyms:=aktrecordsymtable;
  2559. aktrecordsymtable:=symtable;
  2560. { now dereference the definitions }
  2561. tstoredsymtable(symtable).deref;
  2562. aktrecordsymtable:=oldrecsyms;
  2563. { assign TGUID? load only from system unit (unitid=1) }
  2564. if not(assigned(rec_tguid)) and
  2565. (upper(typename)='TGUID') and
  2566. assigned(owner) and
  2567. assigned(owner.name) and
  2568. (owner.name^='SYSTEM') then
  2569. rec_tguid:=self;
  2570. end;
  2571. procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
  2572. var
  2573. oldread_member : boolean;
  2574. begin
  2575. oldread_member:=read_member;
  2576. read_member:=true;
  2577. inherited ppuwritedef(ppufile);
  2578. ppufile.putlongint(savesize);
  2579. ppufile.writeentry(ibrecorddef);
  2580. trecordsymtable(symtable).ppuwrite(ppufile);
  2581. read_member:=oldread_member;
  2582. end;
  2583. function trecorddef.size:longint;
  2584. var
  2585. _resultsize : longint;
  2586. begin
  2587. _resultsize:=symtable.datasize;
  2588. size:=_resultsize;
  2589. end;
  2590. function trecorddef.alignment:longint;
  2591. var
  2592. l : longint;
  2593. hp : tvarsym;
  2594. begin
  2595. { also check the first symbol for it's size, because a
  2596. packed record has dataalignment of 1, but the first
  2597. sym could be a longint which should be aligned on 4 bytes,
  2598. this is compatible with C record packing (PFV) }
  2599. hp:=tvarsym(symtable.symindex.first);
  2600. if assigned(hp) then
  2601. begin
  2602. if hp.vartype.def.deftype in [recorddef,arraydef] then
  2603. l:=hp.vartype.def.alignment
  2604. else
  2605. l:=hp.vartype.def.size;
  2606. if l>symtable.dataalignment then
  2607. begin
  2608. if l>=4 then
  2609. alignment:=4
  2610. else
  2611. if l>=2 then
  2612. alignment:=2
  2613. else
  2614. alignment:=1;
  2615. end
  2616. else
  2617. alignment:=symtable.dataalignment;
  2618. end
  2619. else
  2620. alignment:=symtable.dataalignment;
  2621. end;
  2622. {$ifdef GDB}
  2623. function trecorddef.stabstring : pchar;
  2624. begin
  2625. GetMem(stabrecstring,memsizeinc);
  2626. stabrecsize:=memsizeinc;
  2627. strpcopy(stabRecString,'s'+tostr(size));
  2628. RecOffset := 0;
  2629. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
  2630. strpcopy(strend(StabRecString),';');
  2631. stabstring := strnew(StabRecString);
  2632. Freemem(stabrecstring,stabrecsize);
  2633. end;
  2634. procedure trecorddef.concatstabto(asmlist : taasmoutput);
  2635. begin
  2636. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2637. (is_def_stab_written = not_written) then
  2638. inherited concatstabto(asmlist);
  2639. end;
  2640. {$endif GDB}
  2641. procedure trecorddef.write_child_rtti_data(rt:trttitype);
  2642. begin
  2643. FRTTIType:=rt;
  2644. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
  2645. end;
  2646. procedure trecorddef.write_rtti_data(rt:trttitype);
  2647. begin
  2648. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2649. write_rtti_name;
  2650. rttiList.concat(Tai_const.Create_32bit(size));
  2651. Count:=0;
  2652. FRTTIType:=rt;
  2653. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
  2654. rttiList.concat(Tai_const.Create_32bit(Count));
  2655. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
  2656. end;
  2657. function trecorddef.gettypename : string;
  2658. begin
  2659. gettypename:='<record type>'
  2660. end;
  2661. {***************************************************************************
  2662. TABSTRACTPROCDEF
  2663. ***************************************************************************}
  2664. constructor tabstractprocdef.create;
  2665. begin
  2666. inherited create;
  2667. para:=TParaLinkedList.Create;
  2668. selfpara:=nil;
  2669. minparacount:=0;
  2670. maxparacount:=0;
  2671. proctypeoption:=potype_none;
  2672. proccalloption:=pocall_none;
  2673. procoptions:=[];
  2674. rettype:=voidtype;
  2675. symtablelevel:=0;
  2676. fpu_used:=0;
  2677. savesize:=POINTER_SIZE;
  2678. end;
  2679. destructor tabstractprocdef.destroy;
  2680. begin
  2681. Para.Free;
  2682. inherited destroy;
  2683. end;
  2684. function tabstractprocdef.concatpara(const tt:ttype;sym : tsym;vsp : tvarspez;defval:tsym):tparaitem;
  2685. var
  2686. hp : TParaItem;
  2687. begin
  2688. hp:=TParaItem.Create;
  2689. hp.paratyp:=vsp;
  2690. hp.parasym:=sym;
  2691. hp.paratype:=tt;
  2692. hp.defaultvalue:=defval;
  2693. Para.insert(hp);
  2694. { Don't count hidden parameters }
  2695. if (vsp<>vs_hidden) then
  2696. begin
  2697. if not assigned(defval) then
  2698. inc(minparacount);
  2699. inc(maxparacount);
  2700. end;
  2701. concatpara:=hp;
  2702. end;
  2703. { all functions returning in FPU are
  2704. assume to use 2 FPU registers
  2705. until the function implementation
  2706. is processed PM }
  2707. procedure tabstractprocdef.test_if_fpu_result;
  2708. begin
  2709. if assigned(rettype.def) and
  2710. (rettype.def.deftype=floatdef) then
  2711. fpu_used:=maxfpuregs;
  2712. end;
  2713. procedure tabstractprocdef.deref;
  2714. var
  2715. hp : TParaItem;
  2716. begin
  2717. inherited deref;
  2718. rettype.resolve;
  2719. hp:=TParaItem(Para.first);
  2720. while assigned(hp) do
  2721. begin
  2722. hp.paratype.resolve;
  2723. resolvesym(pointer(hp.defaultvalue));
  2724. resolvesym(pointer(hp.parasym));
  2725. hp:=TParaItem(hp.next);
  2726. end;
  2727. end;
  2728. constructor tabstractprocdef.ppuload(ppufile:tcompilerppufile);
  2729. var
  2730. hp : TParaItem;
  2731. count,i : word;
  2732. begin
  2733. inherited ppuloaddef(ppufile);
  2734. Para:=TParaLinkedList.Create;
  2735. selfpara:=nil;
  2736. minparacount:=0;
  2737. maxparacount:=0;
  2738. ppufile.gettype(rettype);
  2739. fpu_used:=ppufile.getbyte;
  2740. proctypeoption:=tproctypeoption(ppufile.getbyte);
  2741. proccalloption:=tproccalloption(ppufile.getbyte);
  2742. ppufile.getsmallset(procoptions);
  2743. { get the number of parameters }
  2744. count:=ppufile.getbyte;
  2745. savesize:=POINTER_SIZE;
  2746. for i:=1 to count do
  2747. begin
  2748. hp:=TParaItem.Create;
  2749. hp.paratyp:=tvarspez(ppufile.getbyte);
  2750. { hp.register:=tregister(ppufile.getbyte); }
  2751. ppufile.gettype(hp.paratype);
  2752. hp.defaultvalue:=tsym(ppufile.getderef);
  2753. hp.parasym:=tsym(ppufile.getderef);
  2754. { later, we'll gerate this on the fly (FK) }
  2755. ppufile.getdata(hp.paraloc,sizeof(tparalocation));
  2756. { Don't count hidden parameters }
  2757. if (hp.paratyp<>vs_hidden) then
  2758. begin
  2759. if not assigned(hp.defaultvalue) then
  2760. inc(minparacount);
  2761. inc(maxparacount);
  2762. end;
  2763. Para.concat(hp);
  2764. end;
  2765. end;
  2766. procedure tabstractprocdef.ppuwrite(ppufile:tcompilerppufile);
  2767. var
  2768. hp : TParaItem;
  2769. oldintfcrc : boolean;
  2770. begin
  2771. inherited ppuwritedef(ppufile);
  2772. ppufile.puttype(rettype);
  2773. oldintfcrc:=ppufile.do_interface_crc;
  2774. ppufile.do_interface_crc:=false;
  2775. if simplify_ppu then
  2776. fpu_used:=0;
  2777. ppufile.putbyte(fpu_used);
  2778. ppufile.putbyte(ord(proctypeoption));
  2779. ppufile.putbyte(ord(proccalloption));
  2780. ppufile.putsmallset(procoptions);
  2781. ppufile.do_interface_crc:=oldintfcrc;
  2782. ppufile.putbyte(maxparacount);
  2783. hp:=TParaItem(Para.first);
  2784. while assigned(hp) do
  2785. begin
  2786. ppufile.putbyte(byte(hp.paratyp));
  2787. { ppufile.putbyte(byte(hp.register)); }
  2788. ppufile.puttype(hp.paratype);
  2789. ppufile.putderef(hp.defaultvalue);
  2790. ppufile.putderef(hp.parasym);
  2791. ppufile.putdata(hp.paraloc,sizeof(tparalocation));
  2792. hp:=TParaItem(hp.next);
  2793. end;
  2794. end;
  2795. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2796. var
  2797. pdc : TParaItem;
  2798. l : longint;
  2799. begin
  2800. l:=0;
  2801. pdc:=TParaItem(Para.first);
  2802. while assigned(pdc) do
  2803. begin
  2804. inc(l,paramanager.push_size(pdc.paratyp,pdc.paratype.def,proccalloption));
  2805. l:=align(l,alignsize);
  2806. if assigned(pdc.paratype.def) and
  2807. is_special_array(pdc.paratype.def) then
  2808. begin
  2809. inc(l,POINTER_SIZE);
  2810. l:=align(l,alignsize);
  2811. end;
  2812. pdc:=TParaItem(pdc.next);
  2813. end;
  2814. para_size:=l;
  2815. end;
  2816. function tabstractprocdef.typename_paras : string;
  2817. var
  2818. hs,s : string;
  2819. hp : TParaItem;
  2820. hpc : tconstsym;
  2821. begin
  2822. { look for a visible parameter }
  2823. hp:=TParaItem(Para.last);
  2824. while assigned(hp) do
  2825. begin
  2826. if hp.paratyp<>vs_hidden then
  2827. break;
  2828. hp:=TParaItem(hp.previous);
  2829. end;
  2830. { no visible parameter? }
  2831. if not(assigned(hp)) then
  2832. begin
  2833. typename_paras:='';
  2834. exit;
  2835. end;
  2836. hp:=TParaItem(Para.last);
  2837. s:='(';
  2838. while assigned(hp) do
  2839. begin
  2840. if hp.paratyp=vs_var then
  2841. s:=s+'var'
  2842. else if hp.paratyp=vs_const then
  2843. s:=s+'const'
  2844. else if hp.paratyp=vs_out then
  2845. s:=s+'out';
  2846. if hp.paratyp<>vs_hidden then
  2847. begin
  2848. if assigned(hp.paratype.def.typesym) then
  2849. begin
  2850. if hp.paratyp in [vs_var,vs_const,vs_out] then
  2851. s := s + ' ';
  2852. hs:=hp.paratype.def.typesym.realname;
  2853. if hs[1]<>'$' then
  2854. s:=s+hp.paratype.def.typesym.realname
  2855. else
  2856. s:=s+hp.paratype.def.gettypename;
  2857. end;
  2858. { default value }
  2859. if assigned(hp.defaultvalue) then
  2860. begin
  2861. hpc:=tconstsym(hp.defaultvalue);
  2862. hs:='';
  2863. case hpc.consttyp of
  2864. conststring,
  2865. constresourcestring :
  2866. hs:=strpas(pchar(hpc.value.valueptr));
  2867. constreal :
  2868. str(pbestreal(hpc.value.valueptr)^,hs);
  2869. constord :
  2870. hs:=tostr(hpc.value.valueord);
  2871. constpointer :
  2872. hs:=tostr(hpc.value.valueordptr);
  2873. constbool :
  2874. begin
  2875. if hpc.value.valueord<>0 then
  2876. hs:='TRUE'
  2877. else
  2878. hs:='FALSE';
  2879. end;
  2880. constnil :
  2881. hs:='nil';
  2882. constchar :
  2883. hs:=chr(hpc.value.valueord);
  2884. constset :
  2885. hs:='<set>';
  2886. end;
  2887. if hs<>'' then
  2888. s:=s+'="'+hs+'"';
  2889. end;
  2890. end;
  2891. hp:=TParaItem(hp.previous);
  2892. if assigned(hp) and (hp.paratyp<>vs_hidden) then
  2893. s:=s+',';
  2894. end;
  2895. s:=s+')';
  2896. if (po_varargs in procoptions) then
  2897. s:=s+';VarArgs';
  2898. typename_paras:=s;
  2899. end;
  2900. function tabstractprocdef.is_methodpointer:boolean;
  2901. begin
  2902. result:=false;
  2903. end;
  2904. function tabstractprocdef.is_addressonly:boolean;
  2905. begin
  2906. result:=true;
  2907. end;
  2908. {$ifdef GDB}
  2909. function tabstractprocdef.stabstring : pchar;
  2910. begin
  2911. stabstring := strpnew('abstractproc'+numberstring+';');
  2912. end;
  2913. procedure tabstractprocdef.concatstabto(asmlist : taasmoutput);
  2914. begin
  2915. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2916. and (is_def_stab_written = not_written) then
  2917. begin
  2918. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2919. inherited concatstabto(asmlist);
  2920. end;
  2921. end;
  2922. {$endif GDB}
  2923. {***************************************************************************
  2924. TPROCDEF
  2925. ***************************************************************************}
  2926. constructor tprocdef.create;
  2927. begin
  2928. inherited create;
  2929. deftype:=procdef;
  2930. has_mangledname:=false;
  2931. _mangledname:=nil;
  2932. fileinfo:=aktfilepos;
  2933. extnumber:=$ffff;
  2934. aliasnames:=tstringlist.create;
  2935. parast:=tparasymtable.create;
  2936. funcretsym:=nil;
  2937. localst := nil;
  2938. parast.defowner:=self;
  2939. defref:=nil;
  2940. lastwritten:=nil;
  2941. refcount:=0;
  2942. if (cs_browser in aktmoduleswitches) and make_ref then
  2943. begin
  2944. defref:=tref.create(defref,@akttokenpos);
  2945. inc(refcount);
  2946. end;
  2947. lastref:=defref;
  2948. { first, we assume that all registers are used }
  2949. usedintregisters:=ALL_INTREGISTERS;
  2950. usedotherregisters:=ALL_REGISTERS;
  2951. forwarddef:=true;
  2952. interfacedef:=false;
  2953. hasforward:=false;
  2954. _class := nil;
  2955. code:=nil;
  2956. regvarinfo := nil;
  2957. overloadnumber:=0;
  2958. {$ifdef GDB}
  2959. isstabwritten := false;
  2960. {$endif GDB}
  2961. end;
  2962. constructor tprocdef.ppuload(ppufile:tcompilerppufile);
  2963. begin
  2964. inherited ppuload(ppufile);
  2965. deftype:=procdef;
  2966. ppufile.getnormalset(usedintregisters);
  2967. ppufile.getnormalset(usedotherregisters);
  2968. has_mangledname:=boolean(ppufile.getbyte);
  2969. if has_mangledname then
  2970. _mangledname:=stringdup(ppufile.getstring)
  2971. else
  2972. _mangledname:=nil;
  2973. overloadnumber:=ppufile.getword;
  2974. extnumber:=ppufile.getword;
  2975. _class := tobjectdef(ppufile.getderef);
  2976. procsym := tsym(ppufile.getderef);
  2977. ppufile.getposinfo(fileinfo);
  2978. { inline stuff }
  2979. if proccalloption=pocall_inline then
  2980. begin
  2981. funcretsym:=tsym(ppufile.getderef);
  2982. code:=ppuloadnode(ppufile);
  2983. end
  2984. else
  2985. begin
  2986. code := nil;
  2987. funcretsym:=nil;
  2988. end;
  2989. { load para and local symtables }
  2990. parast:=tparasymtable.create;
  2991. tparasymtable(parast).ppuload(ppufile);
  2992. parast.defowner:=self;
  2993. if (proccalloption=pocall_inline) or
  2994. ((current_module.flags and uf_local_browser)<>0) then
  2995. begin
  2996. localst:=tlocalsymtable.create;
  2997. tlocalsymtable(localst).ppuload(ppufile);
  2998. localst.defowner:=self;
  2999. end
  3000. else
  3001. localst:=nil;
  3002. { default values for no persistent data }
  3003. if (cs_link_deffile in aktglobalswitches) and
  3004. (tf_need_export in target_info.flags) and
  3005. (po_exports in procoptions) then
  3006. deffile.AddExport(mangledname);
  3007. aliasnames:=tstringlist.create;
  3008. forwarddef:=false;
  3009. interfacedef:=false;
  3010. hasforward:=false;
  3011. regvarinfo := nil;
  3012. lastref:=nil;
  3013. lastwritten:=nil;
  3014. defref:=nil;
  3015. refcount:=0;
  3016. {$ifdef GDB}
  3017. isstabwritten := false;
  3018. {$endif GDB}
  3019. end;
  3020. destructor tprocdef.destroy;
  3021. begin
  3022. if assigned(defref) then
  3023. begin
  3024. defref.freechain;
  3025. defref.free;
  3026. end;
  3027. aliasnames.free;
  3028. if assigned(parast) then
  3029. begin
  3030. {$ifdef MEMDEBUG}
  3031. memprocparast.start;
  3032. {$endif MEMDEBUG}
  3033. parast.free;
  3034. {$ifdef MEMDEBUG}
  3035. memprocparast.stop;
  3036. {$endif MEMDEBUG}
  3037. end;
  3038. if assigned(localst) and (localst.symtabletype<>staticsymtable) then
  3039. begin
  3040. {$ifdef MEMDEBUG}
  3041. memproclocalst.start;
  3042. {$endif MEMDEBUG}
  3043. localst.free;
  3044. {$ifdef MEMDEBUG}
  3045. memproclocalst.start;
  3046. {$endif MEMDEBUG}
  3047. end;
  3048. if (proccalloption=pocall_inline) and assigned(code) then
  3049. begin
  3050. {$ifdef MEMDEBUG}
  3051. memprocnodetree.start;
  3052. {$endif MEMDEBUG}
  3053. tnode(code).free;
  3054. {$ifdef MEMDEBUG}
  3055. memprocnodetree.start;
  3056. {$endif MEMDEBUG}
  3057. end;
  3058. if assigned(regvarinfo) then
  3059. dispose(pregvarinfo(regvarinfo));
  3060. if (po_msgstr in procoptions) then
  3061. strdispose(messageinf.str);
  3062. if assigned(_mangledname) then
  3063. begin
  3064. {$ifdef MEMDEBUG}
  3065. memmanglednames.start;
  3066. {$endif MEMDEBUG}
  3067. stringdispose(_mangledname);
  3068. {$ifdef MEMDEBUG}
  3069. memmanglednames.stop;
  3070. {$endif MEMDEBUG}
  3071. end;
  3072. inherited destroy;
  3073. end;
  3074. procedure tprocdef.ppuwrite(ppufile:tcompilerppufile);
  3075. var
  3076. oldintfcrc : boolean;
  3077. begin
  3078. inherited ppuwrite(ppufile);
  3079. oldintfcrc:=ppufile.do_interface_crc;
  3080. ppufile.do_interface_crc:=false;
  3081. { set all registers to used for simplified compilation PM }
  3082. if simplify_ppu then
  3083. begin
  3084. usedintregisters:=ALL_INTREGISTERS;
  3085. usedotherregisters:=ALL_REGISTERS;
  3086. end;
  3087. ppufile.putnormalset(usedintregisters);
  3088. ppufile.putnormalset(usedotherregisters);
  3089. ppufile.do_interface_crc:=oldintfcrc;
  3090. ppufile.putbyte(byte(has_mangledname));
  3091. if has_mangledname then
  3092. ppufile.putstring(mangledname);
  3093. ppufile.putword(overloadnumber);
  3094. ppufile.putword(extnumber);
  3095. ppufile.putderef(_class);
  3096. ppufile.putderef(procsym);
  3097. ppufile.putposinfo(fileinfo);
  3098. { inline stuff references to localsymtable, no influence
  3099. on the crc }
  3100. oldintfcrc:=ppufile.do_crc;
  3101. ppufile.do_crc:=false;
  3102. { inline stuff }
  3103. if proccalloption=pocall_inline then
  3104. begin
  3105. ppufile.putderef(funcretsym);
  3106. ppuwritenode(ppufile,code);
  3107. end;
  3108. ppufile.do_crc:=oldintfcrc;
  3109. { write this entry }
  3110. ppufile.writeentry(ibprocdef);
  3111. { Save the para symtable, this is taken from the interface }
  3112. if not assigned(parast) then
  3113. begin
  3114. parast:=tparasymtable.create;
  3115. parast.defowner:=self;
  3116. end;
  3117. tparasymtable(parast).ppuwrite(ppufile);
  3118. { save localsymtable for inline procedures or when local
  3119. browser info is requested, this has no influence on the crc }
  3120. if (proccalloption=pocall_inline) or
  3121. ((current_module.flags and uf_local_browser)<>0) then
  3122. begin
  3123. oldintfcrc:=ppufile.do_crc;
  3124. ppufile.do_crc:=false;
  3125. if not assigned(localst) then
  3126. begin
  3127. localst:=tlocalsymtable.create;
  3128. localst.defowner:=self;
  3129. end;
  3130. tlocalsymtable(localst).ppuwrite(ppufile);
  3131. ppufile.do_crc:=oldintfcrc;
  3132. end;
  3133. end;
  3134. procedure tprocdef.insert_localst;
  3135. begin
  3136. localst:=tlocalsymtable.create;
  3137. localst.defowner:=self;
  3138. { this is used by insert
  3139. to check same names in parast and localst }
  3140. localst.next:=parast;
  3141. end;
  3142. function tprocdef.fullprocname:string;
  3143. var
  3144. s : string;
  3145. begin
  3146. s:='';
  3147. if assigned(_class) then
  3148. begin
  3149. if po_classmethod in procoptions then
  3150. s:=s+'class ';
  3151. s:=s+_class.objrealname^+'.';
  3152. end;
  3153. s:=s+procsym.realname+typename_paras;
  3154. fullprocname:=s;
  3155. end;
  3156. function tprocdef.fullprocnamewithret:string;
  3157. var
  3158. s : string;
  3159. begin
  3160. s:=fullprocname;
  3161. if assigned(rettype.def) and
  3162. not(is_void(rettype.def)) then
  3163. s:=s+' : '+rettype.def.gettypename;
  3164. fullprocnamewithret:=s;
  3165. end;
  3166. function tprocdef.is_methodpointer:boolean;
  3167. begin
  3168. result:=assigned(owner) and
  3169. (owner.symtabletype=objectsymtable);
  3170. end;
  3171. function tprocdef.is_addressonly:boolean;
  3172. begin
  3173. result:=assigned(owner) and
  3174. (owner.symtabletype<>objectsymtable);
  3175. end;
  3176. function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
  3177. begin
  3178. case t of
  3179. gs_local :
  3180. getsymtable:=localst;
  3181. gs_para :
  3182. getsymtable:=parast;
  3183. else
  3184. getsymtable:=nil;
  3185. end;
  3186. end;
  3187. procedure tprocdef.load_references(ppufile:tcompilerppufile;locals:boolean);
  3188. var
  3189. pos : tfileposinfo;
  3190. move_last : boolean;
  3191. begin
  3192. move_last:=lastwritten=lastref;
  3193. while (not ppufile.endofentry) do
  3194. begin
  3195. ppufile.getposinfo(pos);
  3196. inc(refcount);
  3197. lastref:=tref.create(lastref,@pos);
  3198. lastref.is_written:=true;
  3199. if refcount=1 then
  3200. defref:=lastref;
  3201. end;
  3202. if move_last then
  3203. lastwritten:=lastref;
  3204. if ((current_module.flags and uf_local_browser)<>0) and
  3205. locals then
  3206. begin
  3207. tparasymtable(parast).load_references(ppufile,locals);
  3208. tlocalsymtable(localst).load_references(ppufile,locals);
  3209. end;
  3210. end;
  3211. Const
  3212. local_symtable_index : word = $8001;
  3213. function tprocdef.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  3214. var
  3215. ref : tref;
  3216. pdo : tobjectdef;
  3217. move_last : boolean;
  3218. begin
  3219. move_last:=lastwritten=lastref;
  3220. if move_last and
  3221. (((current_module.flags and uf_local_browser)=0) or
  3222. not locals) then
  3223. exit;
  3224. { write address of this symbol }
  3225. ppufile.putderef(self);
  3226. { write refs }
  3227. if assigned(lastwritten) then
  3228. ref:=lastwritten
  3229. else
  3230. ref:=defref;
  3231. while assigned(ref) do
  3232. begin
  3233. if ref.moduleindex=current_module.unit_index then
  3234. begin
  3235. ppufile.putposinfo(ref.posinfo);
  3236. ref.is_written:=true;
  3237. if move_last then
  3238. lastwritten:=ref;
  3239. end
  3240. else if not ref.is_written then
  3241. move_last:=false
  3242. else if move_last then
  3243. lastwritten:=ref;
  3244. ref:=ref.nextref;
  3245. end;
  3246. ppufile.writeentry(ibdefref);
  3247. write_references:=true;
  3248. if ((current_module.flags and uf_local_browser)<>0) and
  3249. locals then
  3250. begin
  3251. pdo:=_class;
  3252. if (owner.symtabletype<>localsymtable) then
  3253. while assigned(pdo) do
  3254. begin
  3255. if pdo.symtable<>aktrecordsymtable then
  3256. begin
  3257. pdo.symtable.unitid:=local_symtable_index;
  3258. inc(local_symtable_index);
  3259. end;
  3260. pdo:=pdo.childof;
  3261. end;
  3262. parast.unitid:=local_symtable_index;
  3263. inc(local_symtable_index);
  3264. localst.unitid:=local_symtable_index;
  3265. inc(local_symtable_index);
  3266. tstoredsymtable(parast).write_references(ppufile,locals);
  3267. tstoredsymtable(localst).write_references(ppufile,locals);
  3268. { decrement for }
  3269. local_symtable_index:=local_symtable_index-2;
  3270. pdo:=_class;
  3271. if (owner.symtabletype<>localsymtable) then
  3272. while assigned(pdo) do
  3273. begin
  3274. if pdo.symtable<>aktrecordsymtable then
  3275. dec(local_symtable_index);
  3276. pdo:=pdo.childof;
  3277. end;
  3278. end;
  3279. end;
  3280. function tprocdef.haspara:boolean;
  3281. begin
  3282. haspara:=assigned(parast.symindex.first);
  3283. end;
  3284. {$ifdef GDB}
  3285. {$ifdef unused}
  3286. { procedure addparaname(p : tsym);
  3287. var vs : char;
  3288. begin
  3289. if tvarsym(p).varspez = vs_value then vs := '1'
  3290. else vs := '0';
  3291. strpcopy(strend(StabRecString),p^.name+':'+tstoreddef(tvarsym(p).vartype.def).numberstring+','+vs+';');
  3292. end; }
  3293. function tprocdef.stabstring : pchar;
  3294. var
  3295. i : longint;
  3296. stabrecstring : pchar;
  3297. begin
  3298. getmem(StabRecString,1024);
  3299. strpcopy(StabRecString,'f'+tstoreddef(rettype.def).numberstring);
  3300. i:=maxparacount;
  3301. if i>0 then
  3302. begin
  3303. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3304. (* confuse gdb !! PM
  3305. if assigned(parast) then
  3306. parast.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3307. else
  3308. begin
  3309. param := para1;
  3310. i := 0;
  3311. while assigned(param) do
  3312. begin
  3313. inc(i);
  3314. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3315. {Here we have lost the parameter names !!}
  3316. {using lower case parameters }
  3317. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3318. +':'+param^.paratype.def.numberstring+','+vartyp+';');
  3319. param := param^.next;
  3320. end;
  3321. end; *)
  3322. {strpcopy(strend(StabRecString),';');}
  3323. end;
  3324. stabstring := strnew(stabrecstring);
  3325. freemem(stabrecstring,1024);
  3326. end;
  3327. {$endif unused}
  3328. function tprocdef.stabstring: pchar;
  3329. Var RType : Char;
  3330. Obj,Info : String;
  3331. stabsstr : string;
  3332. p : pchar;
  3333. begin
  3334. obj := procsym.name;
  3335. info := '';
  3336. if tprocsym(procsym).is_global then
  3337. RType := 'F'
  3338. else
  3339. RType := 'f';
  3340. if assigned(owner) then
  3341. begin
  3342. if (owner.symtabletype = objectsymtable) then
  3343. obj := owner.name^+'__'+procsym.name;
  3344. { this code was correct only as long as the local symboltable
  3345. of the parent had the same name as the function
  3346. but this is no true anymore !! PM
  3347. if (owner.symtabletype=localsymtable) and assigned(owner.name) then
  3348. info := ','+name+','+owner.name^; }
  3349. if (owner.symtabletype=localsymtable) and
  3350. assigned(owner.defowner) and
  3351. assigned(tprocdef(owner.defowner).procsym) then
  3352. info := ','+procsym.name+','+tprocdef(owner.defowner).procsym.name;
  3353. end;
  3354. stabsstr:=mangledname;
  3355. getmem(p,length(stabsstr)+255);
  3356. strpcopy(p,'"'+obj+':'+RType
  3357. +tstoreddef(rettype.def).numberstring+info+'",'+tostr(n_function)
  3358. +',0,'+
  3359. tostr(fileinfo.line)
  3360. +',');
  3361. strpcopy(strend(p),stabsstr);
  3362. stabstring:=strnew(p);
  3363. freemem(p,length(stabsstr)+255);
  3364. end;
  3365. procedure tprocdef.concatstabto(asmlist : taasmoutput);
  3366. begin
  3367. if (proccalloption=pocall_internproc) then
  3368. exit;
  3369. if not isstabwritten then
  3370. asmList.concat(Tai_stabs.Create(stabstring));
  3371. isstabwritten := true;
  3372. if assigned(parast) then
  3373. tstoredsymtable(parast).concatstabto(asmlist);
  3374. { local type defs and vars should not be written
  3375. inside the main proc stab }
  3376. if assigned(localst) and
  3377. (lexlevel>main_program_level) then
  3378. tstoredsymtable(localst).concatstabto(asmlist);
  3379. is_def_stab_written := written;
  3380. end;
  3381. {$endif GDB}
  3382. procedure tprocdef.deref;
  3383. var
  3384. oldlocalsymtable : tsymtable;
  3385. begin
  3386. inherited deref;
  3387. resolvedef(pointer(_class));
  3388. { parast }
  3389. oldlocalsymtable:=aktlocalsymtable;
  3390. aktlocalsymtable:=parast;
  3391. tparasymtable(parast).deref;
  3392. aktlocalsymtable:=oldlocalsymtable;
  3393. { procsym that originaly defined this definition, should be in the
  3394. same symtable }
  3395. resolvesym(pointer(procsym));
  3396. end;
  3397. procedure tprocdef.derefimpl;
  3398. var
  3399. oldlocalsymtable : tsymtable;
  3400. begin
  3401. { locals }
  3402. if assigned(localst) then
  3403. begin
  3404. { localst }
  3405. oldlocalsymtable:=aktlocalsymtable;
  3406. aktlocalsymtable:=localst;
  3407. { we can deref both interface and implementation parts }
  3408. tlocalsymtable(localst).deref;
  3409. tlocalsymtable(localst).derefimpl;
  3410. aktlocalsymtable:=oldlocalsymtable;
  3411. { funcretsym, this is always located in the localst }
  3412. resolvesym(pointer(funcretsym));
  3413. end
  3414. else
  3415. begin
  3416. { safety }
  3417. funcretsym:=nil;
  3418. end;
  3419. { inline tree }
  3420. if (proccalloption=pocall_inline) then
  3421. code.derefimpl;
  3422. end;
  3423. function tprocdef.gettypename : string;
  3424. begin
  3425. gettypename := FullProcName+';'+ProcCallOptionStr[proccalloption];
  3426. end;
  3427. function tprocdef.mangledname : string;
  3428. var
  3429. s : string;
  3430. hp : TParaItem;
  3431. begin
  3432. if assigned(_mangledname) then
  3433. begin
  3434. mangledname:=_mangledname^;
  3435. exit;
  3436. end;
  3437. { we need to use the symtable where the procsym is inserted,
  3438. because that is visible to the world }
  3439. s:=mangledname_prefix('',procsym.owner)+procsym.name;
  3440. if overloadnumber>0 then
  3441. s:=s+'$'+tostr(overloadnumber);
  3442. { add parameter types }
  3443. hp:=TParaItem(Para.last);
  3444. if assigned(hp) and (hp.paratyp<>vs_hidden) then
  3445. s:=s+'$';
  3446. while assigned(hp) do
  3447. begin
  3448. if hp.paratyp<>vs_hidden then
  3449. s:=s+hp.paratype.def.mangledparaname;
  3450. hp:=TParaItem(hp.previous);
  3451. if assigned(hp) and (hp.paratyp<>vs_hidden) then
  3452. s:=s+'$';
  3453. end;
  3454. _mangledname:=stringdup(s);
  3455. mangledname:=_mangledname^;
  3456. end;
  3457. function tprocdef.cplusplusmangledname : string;
  3458. function getcppparaname(p : tdef) : string;
  3459. const
  3460. ordtype2str : array[tbasetype] of string[2] = (
  3461. '',
  3462. 'Uc','Us','Ui','Us',
  3463. 'Sc','s','i','x',
  3464. 'b','b','b',
  3465. 'c','w');
  3466. var
  3467. s : string;
  3468. begin
  3469. case p.deftype of
  3470. orddef:
  3471. s:=ordtype2str[torddef(p).typ];
  3472. pointerdef:
  3473. s:='P'+getcppparaname(tpointerdef(p).pointertype.def);
  3474. else
  3475. internalerror(2103001);
  3476. end;
  3477. getcppparaname:=s;
  3478. end;
  3479. var
  3480. s,s2 : string;
  3481. param : TParaItem;
  3482. begin
  3483. s := procsym.realname;
  3484. if procsym.owner.symtabletype=objectsymtable then
  3485. begin
  3486. s2:=upper(tobjectdef(procsym.owner.defowner).typesym.realname);
  3487. case proctypeoption of
  3488. potype_destructor:
  3489. s:='_$_'+tostr(length(s2))+s2;
  3490. potype_constructor:
  3491. s:='___'+tostr(length(s2))+s2;
  3492. else
  3493. s:='_'+s+'__'+tostr(length(s2))+s2;
  3494. end;
  3495. end
  3496. else s:=s+'__';
  3497. s:=s+'F';
  3498. { concat modifiers }
  3499. { !!!!! }
  3500. { now we handle the parameters }
  3501. param := TParaItem(Para.first);
  3502. if assigned(param) then
  3503. while assigned(param) do
  3504. begin
  3505. s2:=getcppparaname(param.paratype.def);
  3506. if param.paratyp in [vs_var,vs_out] then
  3507. s2:='R'+s2;
  3508. s:=s+s2;
  3509. param:=TParaItem(param.next);
  3510. end
  3511. else
  3512. s:=s+'v';
  3513. cplusplusmangledname:=s;
  3514. end;
  3515. procedure tprocdef.setmangledname(const s : string);
  3516. begin
  3517. stringdispose(_mangledname);
  3518. _mangledname:=stringdup(s);
  3519. has_mangledname:=true;
  3520. end;
  3521. {***************************************************************************
  3522. TPROCVARDEF
  3523. ***************************************************************************}
  3524. constructor tprocvardef.create;
  3525. begin
  3526. inherited create;
  3527. deftype:=procvardef;
  3528. end;
  3529. constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
  3530. begin
  3531. inherited ppuload(ppufile);
  3532. deftype:=procvardef;
  3533. end;
  3534. procedure tprocvardef.ppuwrite(ppufile:tcompilerppufile);
  3535. begin
  3536. { here we cannot get a real good value so just give something }
  3537. { plausible (PM) }
  3538. { a more secure way would be
  3539. to allways store in a temp }
  3540. if is_fpu(rettype.def) then
  3541. fpu_used:={2}maxfpuregs
  3542. else
  3543. fpu_used:=0;
  3544. inherited ppuwrite(ppufile);
  3545. ppufile.writeentry(ibprocvardef);
  3546. end;
  3547. function tprocvardef.size : longint;
  3548. begin
  3549. if (po_methodpointer in procoptions) and
  3550. not(po_addressonly in procoptions) then
  3551. size:=2*POINTER_SIZE
  3552. else
  3553. size:=POINTER_SIZE;
  3554. end;
  3555. function tprocvardef.is_methodpointer:boolean;
  3556. begin
  3557. result:=(po_methodpointer in procoptions);
  3558. end;
  3559. function tprocvardef.is_addressonly:boolean;
  3560. begin
  3561. result:=not(po_methodpointer in procoptions) or
  3562. (po_addressonly in procoptions);
  3563. end;
  3564. {$ifdef GDB}
  3565. function tprocvardef.stabstring : pchar;
  3566. var
  3567. nss : pchar;
  3568. { i : longint; }
  3569. begin
  3570. { i := maxparacount; }
  3571. getmem(nss,1024);
  3572. { it is not a function but a function pointer !! (PM) }
  3573. strpcopy(nss,'*f'+tstoreddef(rettype.def).numberstring{+','+tostr(i)}+';');
  3574. { this confuses gdb !!
  3575. we should use 'F' instead of 'f' but
  3576. as we use c++ language mode
  3577. it does not like that either
  3578. Please do not remove this part
  3579. might be used once
  3580. gdb for pascal is ready PM }
  3581. (*
  3582. param := para1;
  3583. i := 0;
  3584. while assigned(param) do
  3585. begin
  3586. inc(i);
  3587. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3588. {Here we have lost the parameter names !!}
  3589. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def.numberstring+','+vartyp+';');
  3590. strcat(nss,pst);
  3591. strdispose(pst);
  3592. param := param^.next;
  3593. end; *)
  3594. {strpcopy(strend(nss),';');}
  3595. stabstring := strnew(nss);
  3596. freemem(nss,1024);
  3597. end;
  3598. procedure tprocvardef.concatstabto(asmlist : taasmoutput);
  3599. begin
  3600. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3601. and (is_def_stab_written = not_written) then
  3602. inherited concatstabto(asmlist);
  3603. is_def_stab_written:=written;
  3604. end;
  3605. {$endif GDB}
  3606. procedure tprocvardef.write_rtti_data(rt:trttitype);
  3607. var
  3608. pdc : TParaItem;
  3609. methodkind, paraspec : byte;
  3610. begin
  3611. if po_methodpointer in procoptions then
  3612. begin
  3613. { write method id and name }
  3614. rttiList.concat(Tai_const.Create_8bit(tkmethod));
  3615. write_rtti_name;
  3616. { write kind of method (can only be function or procedure)}
  3617. if rettype.def = voidtype.def then
  3618. methodkind := mkProcedure
  3619. else
  3620. methodkind := mkFunction;
  3621. rttiList.concat(Tai_const.Create_8bit(methodkind));
  3622. { get # of parameters }
  3623. rttiList.concat(Tai_const.Create_8bit(maxparacount));
  3624. { write parameter info. The parameters must be written in reverse order
  3625. if this method uses right to left parameter pushing! }
  3626. if (po_leftright in procoptions) then
  3627. pdc:=TParaItem(Para.last)
  3628. else
  3629. pdc:=TParaItem(Para.first);
  3630. while assigned(pdc) do
  3631. begin
  3632. case pdc.paratyp of
  3633. vs_value: paraspec := 0;
  3634. vs_const: paraspec := pfConst;
  3635. vs_var : paraspec := pfVar;
  3636. vs_out : paraspec := pfOut;
  3637. end;
  3638. { write flags for current parameter }
  3639. rttiList.concat(Tai_const.Create_8bit(paraspec));
  3640. { write name of current parameter ### how can I get this??? (sg)}
  3641. rttiList.concat(Tai_const.Create_8bit(0));
  3642. { write name of type of current parameter }
  3643. tstoreddef(pdc.paratype.def).write_rtti_name;
  3644. if (po_leftright in procoptions) then
  3645. pdc:=TParaItem(pdc.previous)
  3646. else
  3647. pdc:=TParaItem(pdc.next);
  3648. end;
  3649. { write name of result type }
  3650. tstoreddef(rettype.def).write_rtti_name;
  3651. end;
  3652. end;
  3653. function tprocvardef.is_publishable : boolean;
  3654. begin
  3655. is_publishable:=(po_methodpointer in procoptions);
  3656. end;
  3657. function tprocvardef.gettypename : string;
  3658. var
  3659. s: string;
  3660. begin
  3661. s:='<';
  3662. if po_classmethod in procoptions then
  3663. s := s+'class method type of'
  3664. else
  3665. if po_addressonly in procoptions then
  3666. s := s+'address of'
  3667. else
  3668. s := s+'procedure variable type of';
  3669. if assigned(rettype.def) and
  3670. (rettype.def<>voidtype.def) then
  3671. s:=s+' function'+typename_paras+':'+rettype.def.gettypename
  3672. else
  3673. s:=s+' procedure'+typename_paras;
  3674. if po_methodpointer in procoptions then
  3675. s := s+' of object';
  3676. gettypename := s+';'+ProcCallOptionStr[proccalloption]+'>';
  3677. end;
  3678. {***************************************************************************
  3679. TOBJECTDEF
  3680. ***************************************************************************}
  3681. constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  3682. begin
  3683. inherited create;
  3684. objecttype:=ot;
  3685. deftype:=objectdef;
  3686. objectoptions:=[];
  3687. childof:=nil;
  3688. symtable:=tobjectsymtable.create(n);
  3689. { create space for vmt !! }
  3690. vmt_offset:=0;
  3691. symtable.datasize:=0;
  3692. symtable.defowner:=self;
  3693. { recordalign -1 means C record packing, that starts
  3694. with an alignment of 1 }
  3695. if aktalignment.recordalignmax=-1 then
  3696. symtable.dataalignment:=1
  3697. else
  3698. symtable.dataalignment:=aktalignment.recordalignmax;
  3699. lastvtableindex:=0;
  3700. set_parent(c);
  3701. objname:=stringdup(upper(n));
  3702. objrealname:=stringdup(n);
  3703. if objecttype in [odt_interfacecorba,odt_interfacecom] then
  3704. prepareguid;
  3705. { setup implemented interfaces }
  3706. if objecttype in [odt_class,odt_interfacecorba] then
  3707. implementedinterfaces:=timplementedinterfaces.create
  3708. else
  3709. implementedinterfaces:=nil;
  3710. {$ifdef GDB}
  3711. writing_class_record_stab:=false;
  3712. {$endif GDB}
  3713. end;
  3714. constructor tobjectdef.ppuload(ppufile:tcompilerppufile);
  3715. var
  3716. oldread_member : boolean;
  3717. i,implintfcount: longint;
  3718. begin
  3719. inherited ppuloaddef(ppufile);
  3720. deftype:=objectdef;
  3721. objecttype:=tobjectdeftype(ppufile.getbyte);
  3722. savesize:=ppufile.getlongint;
  3723. vmt_offset:=ppufile.getlongint;
  3724. objrealname:=stringdup(ppufile.getstring);
  3725. objname:=stringdup(upper(objrealname^));
  3726. childof:=tobjectdef(ppufile.getderef);
  3727. ppufile.getsmallset(objectoptions);
  3728. { load guid }
  3729. iidstr:=nil;
  3730. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3731. begin
  3732. new(iidguid);
  3733. ppufile.getguid(iidguid^);
  3734. iidstr:=stringdup(ppufile.getstring);
  3735. lastvtableindex:=ppufile.getlongint;
  3736. end;
  3737. { load implemented interfaces }
  3738. if objecttype in [odt_class,odt_interfacecorba] then
  3739. begin
  3740. implementedinterfaces:=timplementedinterfaces.create;
  3741. implintfcount:=ppufile.getlongint;
  3742. for i:=1 to implintfcount do
  3743. begin
  3744. implementedinterfaces.addintfref(ppufile.getderef);
  3745. implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
  3746. end;
  3747. end
  3748. else
  3749. implementedinterfaces:=nil;
  3750. oldread_member:=read_member;
  3751. read_member:=true;
  3752. symtable:=tobjectsymtable.create(objrealname^);
  3753. tobjectsymtable(symtable).ppuload(ppufile);
  3754. read_member:=oldread_member;
  3755. symtable.defowner:=self;
  3756. { handles the predefined class tobject }
  3757. { the last TOBJECT which is loaded gets }
  3758. { it ! }
  3759. if (childof=nil) and
  3760. (objecttype=odt_class) and
  3761. (objname^='TOBJECT') then
  3762. class_tobject:=self;
  3763. if (childof=nil) and
  3764. (objecttype=odt_interfacecom) and
  3765. (objname^='IUNKNOWN') then
  3766. interface_iunknown:=self;
  3767. {$ifdef GDB}
  3768. writing_class_record_stab:=false;
  3769. {$endif GDB}
  3770. end;
  3771. destructor tobjectdef.destroy;
  3772. begin
  3773. if assigned(symtable) then
  3774. symtable.free;
  3775. stringdispose(objname);
  3776. stringdispose(objrealname);
  3777. if assigned(iidstr) then
  3778. stringdispose(iidstr);
  3779. if assigned(implementedinterfaces) then
  3780. implementedinterfaces.free;
  3781. if assigned(iidguid) then
  3782. dispose(iidguid);
  3783. inherited destroy;
  3784. end;
  3785. procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile);
  3786. var
  3787. oldread_member : boolean;
  3788. implintfcount : longint;
  3789. i : longint;
  3790. begin
  3791. inherited ppuwritedef(ppufile);
  3792. ppufile.putbyte(byte(objecttype));
  3793. ppufile.putlongint(size);
  3794. ppufile.putlongint(vmt_offset);
  3795. ppufile.putstring(objrealname^);
  3796. ppufile.putderef(childof);
  3797. ppufile.putsmallset(objectoptions);
  3798. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3799. begin
  3800. ppufile.putguid(iidguid^);
  3801. ppufile.putstring(iidstr^);
  3802. ppufile.putlongint(lastvtableindex);
  3803. end;
  3804. if objecttype in [odt_class,odt_interfacecorba] then
  3805. begin
  3806. implintfcount:=implementedinterfaces.count;
  3807. ppufile.putlongint(implintfcount);
  3808. for i:=1 to implintfcount do
  3809. begin
  3810. ppufile.putderef(implementedinterfaces.interfaces(i));
  3811. ppufile.putlongint(implementedinterfaces.ioffsets(i)^);
  3812. end;
  3813. end;
  3814. ppufile.writeentry(ibobjectdef);
  3815. oldread_member:=read_member;
  3816. read_member:=true;
  3817. tobjectsymtable(symtable).ppuwrite(ppufile);
  3818. read_member:=oldread_member;
  3819. end;
  3820. procedure tobjectdef.deref;
  3821. var
  3822. oldrecsyms : tsymtable;
  3823. begin
  3824. inherited deref;
  3825. resolvedef(pointer(childof));
  3826. oldrecsyms:=aktrecordsymtable;
  3827. aktrecordsymtable:=symtable;
  3828. tstoredsymtable(symtable).deref;
  3829. aktrecordsymtable:=oldrecsyms;
  3830. if objecttype in [odt_class,odt_interfacecorba] then
  3831. implementedinterfaces.deref;
  3832. end;
  3833. procedure tobjectdef.prepareguid;
  3834. begin
  3835. { set up guid }
  3836. if not assigned(iidguid) then
  3837. begin
  3838. new(iidguid);
  3839. fillchar(iidguid^,sizeof(iidguid^),0); { default null guid }
  3840. end;
  3841. { setup iidstring }
  3842. if not assigned(iidstr) then
  3843. iidstr:=stringdup(''); { default is empty string }
  3844. end;
  3845. procedure tobjectdef.set_parent( c : tobjectdef);
  3846. begin
  3847. { nothing to do if the parent was not forward !}
  3848. if assigned(childof) then
  3849. exit;
  3850. childof:=c;
  3851. { some options are inherited !! }
  3852. if assigned(c) then
  3853. begin
  3854. { only important for classes }
  3855. lastvtableindex:=c.lastvtableindex;
  3856. objectoptions:=objectoptions+(c.objectoptions*
  3857. [oo_has_virtual,oo_has_private,oo_has_protected,
  3858. oo_has_constructor,oo_has_destructor]);
  3859. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3860. begin
  3861. { add the data of the anchestor class }
  3862. inc(symtable.datasize,c.symtable.datasize);
  3863. if (oo_has_vmt in objectoptions) and
  3864. (oo_has_vmt in c.objectoptions) then
  3865. dec(symtable.datasize,POINTER_SIZE);
  3866. { if parent has a vmt field then
  3867. the offset is the same for the child PM }
  3868. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  3869. begin
  3870. vmt_offset:=c.vmt_offset;
  3871. include(objectoptions,oo_has_vmt);
  3872. end;
  3873. end;
  3874. end;
  3875. savesize := symtable.datasize;
  3876. end;
  3877. procedure tobjectdef.insertvmt;
  3878. begin
  3879. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3880. exit;
  3881. if (oo_has_vmt in objectoptions) then
  3882. internalerror(12345)
  3883. else
  3884. begin
  3885. symtable.datasize:=align(symtable.datasize,symtable.dataalignment);
  3886. vmt_offset:=symtable.datasize;
  3887. inc(symtable.datasize,POINTER_SIZE);
  3888. include(objectoptions,oo_has_vmt);
  3889. end;
  3890. end;
  3891. procedure tobjectdef.check_forwards;
  3892. begin
  3893. if not(objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3894. tstoredsymtable(symtable).check_forwards;
  3895. if (oo_is_forward in objectoptions) then
  3896. begin
  3897. { ok, in future, the forward can be resolved }
  3898. Message1(sym_e_class_forward_not_resolved,objrealname^);
  3899. exclude(objectoptions,oo_is_forward);
  3900. end;
  3901. end;
  3902. { true, if self inherits from d (or if they are equal) }
  3903. function tobjectdef.is_related(d : tobjectdef) : boolean;
  3904. var
  3905. hp : tobjectdef;
  3906. begin
  3907. hp:=self;
  3908. while assigned(hp) do
  3909. begin
  3910. if hp=d then
  3911. begin
  3912. is_related:=true;
  3913. exit;
  3914. end;
  3915. hp:=hp.childof;
  3916. end;
  3917. is_related:=false;
  3918. end;
  3919. (* procedure tobjectdef._searchdestructor(sym : tnamedindexitem;arg:pointer);
  3920. var
  3921. p : pprocdeflist;
  3922. begin
  3923. { if we found already a destructor, then we exit }
  3924. if assigned(sd) then
  3925. exit;
  3926. if tsym(sym).typ=procsym then
  3927. begin
  3928. p:=tprocsym(sym).defs;
  3929. while assigned(p) do
  3930. begin
  3931. if p^.def.proctypeoption=potype_destructor then
  3932. begin
  3933. sd:=p^.def;
  3934. exit;
  3935. end;
  3936. p:=p^.next;
  3937. end;
  3938. end;
  3939. end;*)
  3940. procedure Tobjectdef._searchdestructor(sym:Tnamedindexitem;arg:pointer);
  3941. begin
  3942. { if we found already a destructor, then we exit }
  3943. if (sd=nil) and (Tsym(sym).typ=procsym) then
  3944. sd:=Tprocsym(sym).search_procdef_bytype(potype_destructor);
  3945. end;
  3946. function tobjectdef.searchdestructor : tprocdef;
  3947. var
  3948. o : tobjectdef;
  3949. begin
  3950. searchdestructor:=nil;
  3951. o:=self;
  3952. sd:=nil;
  3953. while assigned(o) do
  3954. begin
  3955. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor,nil);
  3956. if assigned(sd) then
  3957. begin
  3958. searchdestructor:=sd;
  3959. exit;
  3960. end;
  3961. o:=o.childof;
  3962. end;
  3963. end;
  3964. function tobjectdef.size : longint;
  3965. var
  3966. _resultsize : longint;
  3967. begin
  3968. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3969. _resultsize:=POINTER_SIZE
  3970. else
  3971. _resultsize:=symtable.datasize;
  3972. size := _resultsize;
  3973. end;
  3974. function tobjectdef.alignment:longint;
  3975. begin
  3976. alignment:=symtable.dataalignment;
  3977. end;
  3978. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3979. begin
  3980. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3981. case objecttype of
  3982. odt_class:
  3983. vmtmethodoffset:=(index+12)*POINTER_SIZE;
  3984. odt_interfacecom,odt_interfacecorba:
  3985. vmtmethodoffset:=index*POINTER_SIZE;
  3986. else
  3987. {$ifdef WITHDMT}
  3988. vmtmethodoffset:=(index+4)*POINTER_SIZE;
  3989. {$else WITHDMT}
  3990. vmtmethodoffset:=(index+3)*POINTER_SIZE;
  3991. {$endif WITHDMT}
  3992. end;
  3993. end;
  3994. function tobjectdef.vmt_mangledname : string;
  3995. begin
  3996. if not(oo_has_vmt in objectoptions) then
  3997. Message1(parser_n_object_has_no_vmt,objrealname^);
  3998. vmt_mangledname:=mangledname_prefix('VMT',owner)+objname^;
  3999. end;
  4000. function tobjectdef.rtti_name : string;
  4001. begin
  4002. rtti_name:=mangledname_prefix('RTTI',owner)+objname^;
  4003. end;
  4004. {$ifdef GDB}
  4005. procedure tobjectdef.addprocname(p :tnamedindexitem;arg:pointer);
  4006. var virtualind,argnames : string;
  4007. news, newrec : pchar;
  4008. pd,ipd : tprocdef;
  4009. lindex : longint;
  4010. para : TParaItem;
  4011. arglength : byte;
  4012. sp : char;
  4013. begin
  4014. If tsym(p).typ = procsym then
  4015. begin
  4016. pd := tprocsym(p).first_procdef;
  4017. { this will be used for full implementation of object stabs
  4018. not yet done }
  4019. ipd := Tprocsym(p).last_procdef;
  4020. if (po_virtualmethod in pd.procoptions) then
  4021. begin
  4022. lindex := pd.extnumber;
  4023. {doesnt seem to be necessary
  4024. lindex := lindex or $80000000;}
  4025. virtualind := '*'+tostr(lindex)+';'+ipd._class.classnumberstring+';'
  4026. end
  4027. else
  4028. virtualind := '.';
  4029. { used by gdbpas to recognize constructor and destructors }
  4030. if (pd.proctypeoption=potype_constructor) then
  4031. argnames:='__ct__'
  4032. else if (pd.proctypeoption=potype_destructor) then
  4033. argnames:='__dt__'
  4034. else
  4035. argnames := '';
  4036. { arguments are not listed here }
  4037. {we don't need another definition}
  4038. para := TParaItem(pd.Para.first);
  4039. while assigned(para) do
  4040. begin
  4041. if Para.paratype.def.deftype = formaldef then
  4042. begin
  4043. if Para.paratyp=vs_var then
  4044. argnames := argnames+'3var'
  4045. else if Para.paratyp=vs_const then
  4046. argnames:=argnames+'5const'
  4047. else if Para.paratyp=vs_out then
  4048. argnames:=argnames+'3out';
  4049. end
  4050. else
  4051. begin
  4052. { if the arg definition is like (v: ^byte;..
  4053. there is no sym attached to data !!! }
  4054. if assigned(Para.paratype.def.typesym) then
  4055. begin
  4056. arglength := length(Para.paratype.def.typesym.name);
  4057. argnames := argnames + tostr(arglength)+Para.paratype.def.typesym.name;
  4058. end
  4059. else
  4060. begin
  4061. argnames:=argnames+'11unnamedtype';
  4062. end;
  4063. end;
  4064. para := TParaItem(Para.next);
  4065. end;
  4066. ipd.is_def_stab_written := written;
  4067. { here 2A must be changed for private and protected }
  4068. { 0 is private 1 protected and 2 public }
  4069. if (sp_private in tsym(p).symoptions) then sp:='0'
  4070. else if (sp_protected in tsym(p).symoptions) then sp:='1'
  4071. else sp:='2';
  4072. newrec := strpnew(p.name+'::'+ipd.numberstring
  4073. +'=##'+tstoreddef(pd.rettype.def).numberstring+';:'+argnames+';'+sp+'A'
  4074. +virtualind+';');
  4075. { get spare place for a string at the end }
  4076. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  4077. begin
  4078. getmem(news,stabrecsize+memsizeinc);
  4079. strcopy(news,stabrecstring);
  4080. freemem(stabrecstring,stabrecsize);
  4081. stabrecsize:=stabrecsize+memsizeinc;
  4082. stabrecstring:=news;
  4083. end;
  4084. strcat(StabRecstring,newrec);
  4085. {freemem(newrec,memsizeinc); }
  4086. strdispose(newrec);
  4087. {This should be used for case !!
  4088. RecOffset := RecOffset + pd.size;}
  4089. end;
  4090. end;
  4091. function tobjectdef.stabstring : pchar;
  4092. var anc : tobjectdef;
  4093. oldrec : pchar;
  4094. oldrecsize,oldrecoffset : longint;
  4095. str_end : string;
  4096. begin
  4097. if not (objecttype=odt_class) or writing_class_record_stab then
  4098. begin
  4099. oldrec := stabrecstring;
  4100. oldrecsize:=stabrecsize;
  4101. stabrecsize:=memsizeinc;
  4102. GetMem(stabrecstring,stabrecsize);
  4103. strpcopy(stabRecString,'s'+tostr(symtable.datasize));
  4104. if assigned(childof) then
  4105. begin
  4106. {only one ancestor not virtual, public, at base offset 0 }
  4107. { !1 , 0 2 0 , }
  4108. strpcopy(strend(stabrecstring),'!1,020,'+childof.classnumberstring+';');
  4109. end;
  4110. {virtual table to implement yet}
  4111. OldRecOffset:=RecOffset;
  4112. RecOffset := 0;
  4113. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
  4114. RecOffset:=OldRecOffset;
  4115. if (oo_has_vmt in objectoptions) then
  4116. if not assigned(childof) or not(oo_has_vmt in childof.objectoptions) then
  4117. begin
  4118. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  4119. +','+tostr(vmt_offset*8)+';');
  4120. end;
  4121. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname,nil);
  4122. if (oo_has_vmt in objectoptions) then
  4123. begin
  4124. anc := self;
  4125. while assigned(anc.childof) and (oo_has_vmt in anc.childof.objectoptions) do
  4126. anc := anc.childof;
  4127. { just in case anc = self }
  4128. str_end:=';~%'+anc.classnumberstring+';';
  4129. end
  4130. else
  4131. str_end:=';';
  4132. strpcopy(strend(stabrecstring),str_end);
  4133. stabstring := strnew(StabRecString);
  4134. freemem(stabrecstring,stabrecsize);
  4135. stabrecstring := oldrec;
  4136. stabrecsize:=oldrecsize;
  4137. end
  4138. else
  4139. begin
  4140. stabstring:=strpnew('*'+classnumberstring);
  4141. end;
  4142. end;
  4143. procedure tobjectdef.set_globalnb;
  4144. begin
  4145. globalnb:=PglobalTypeCount^;
  4146. inc(PglobalTypeCount^);
  4147. { classes need two type numbers, the globalnb is set to the ptr }
  4148. if objecttype=odt_class then
  4149. begin
  4150. globalnb:=PGlobalTypeCount^;
  4151. inc(PglobalTypeCount^);
  4152. end;
  4153. end;
  4154. function tobjectdef.classnumberstring : string;
  4155. begin
  4156. { write stabs again if needed }
  4157. numberstring;
  4158. if objecttype=odt_class then
  4159. begin
  4160. dec(globalnb);
  4161. classnumberstring:=numberstring;
  4162. inc(globalnb);
  4163. end
  4164. else
  4165. classnumberstring:=numberstring;
  4166. end;
  4167. function tobjectdef.allstabstring : pchar;
  4168. var stabchar : string[2];
  4169. ss,st : pchar;
  4170. sname : string;
  4171. sym_line_no : longint;
  4172. begin
  4173. ss := stabstring;
  4174. getmem(st,strlen(ss)+512);
  4175. stabchar := 't';
  4176. if deftype in tagtypes then
  4177. stabchar := 'Tt';
  4178. if assigned(typesym) then
  4179. begin
  4180. sname := typesym.name;
  4181. sym_line_no:=typesym.fileinfo.line;
  4182. end
  4183. else
  4184. begin
  4185. sname := ' ';
  4186. sym_line_no:=0;
  4187. end;
  4188. if writing_class_record_stab then
  4189. strpcopy(st,'"'+sname+':'+stabchar+classnumberstring+'=')
  4190. else
  4191. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  4192. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  4193. allstabstring := strnew(st);
  4194. freemem(st,strlen(ss)+512);
  4195. strdispose(ss);
  4196. end;
  4197. procedure tobjectdef.concatstabto(asmlist : taasmoutput);
  4198. var st : pstring;
  4199. begin
  4200. if objecttype<>odt_class then
  4201. begin
  4202. inherited concatstabto(asmlist);
  4203. exit;
  4204. end;
  4205. if ((typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  4206. (is_def_stab_written = not_written) then
  4207. begin
  4208. if globalnb=0 then
  4209. set_globalnb;
  4210. { Write the record class itself }
  4211. writing_class_record_stab:=true;
  4212. inherited concatstabto(asmlist);
  4213. writing_class_record_stab:=false;
  4214. { Write the invisible pointer class }
  4215. is_def_stab_written:=not_written;
  4216. if assigned(typesym) then
  4217. begin
  4218. st:=typesym.FName;
  4219. typesym.FName:=stringdup(' ');
  4220. end;
  4221. inherited concatstabto(asmlist);
  4222. if assigned(typesym) then
  4223. begin
  4224. stringdispose(typesym.FName);
  4225. typesym.FName:=st;
  4226. end;
  4227. end;
  4228. end;
  4229. {$endif GDB}
  4230. function tobjectdef.needs_inittable : boolean;
  4231. begin
  4232. case objecttype of
  4233. odt_class :
  4234. needs_inittable:=false;
  4235. odt_interfacecom:
  4236. needs_inittable:=true;
  4237. odt_interfacecorba:
  4238. needs_inittable:=is_related(interface_iunknown);
  4239. odt_object:
  4240. needs_inittable:=tobjectsymtable(symtable).needs_init_final;
  4241. else
  4242. internalerror(200108267);
  4243. end;
  4244. end;
  4245. function tobjectdef.members_need_inittable : boolean;
  4246. begin
  4247. members_need_inittable:=tobjectsymtable(symtable).needs_init_final;
  4248. end;
  4249. procedure tobjectdef.count_published_properties(sym:tnamedindexitem;arg:pointer);
  4250. begin
  4251. if needs_prop_entry(tsym(sym)) and
  4252. (tsym(sym).typ<>varsym) then
  4253. inc(count);
  4254. end;
  4255. procedure tobjectdef.write_property_info(sym : tnamedindexitem;arg:pointer);
  4256. var
  4257. proctypesinfo : byte;
  4258. procedure writeproc(proc : tsymlist; shiftvalue : byte);
  4259. var
  4260. typvalue : byte;
  4261. hp : psymlistitem;
  4262. address : longint;
  4263. begin
  4264. if not(assigned(proc) and assigned(proc.firstsym)) then
  4265. begin
  4266. rttiList.concat(Tai_const.Create_32bit(1));
  4267. typvalue:=3;
  4268. end
  4269. else if proc.firstsym^.sym.typ=varsym then
  4270. begin
  4271. address:=0;
  4272. hp:=proc.firstsym;
  4273. while assigned(hp) do
  4274. begin
  4275. inc(address,tvarsym(hp^.sym).address);
  4276. hp:=hp^.next;
  4277. end;
  4278. rttiList.concat(Tai_const.Create_32bit(address));
  4279. typvalue:=0;
  4280. end
  4281. else
  4282. begin
  4283. if not(po_virtualmethod in tprocdef(proc.def).procoptions) then
  4284. begin
  4285. rttiList.concat(Tai_const_symbol.Createname(tprocdef(proc.def).mangledname));
  4286. typvalue:=1;
  4287. end
  4288. else
  4289. begin
  4290. { virtual method, write vmt offset }
  4291. rttiList.concat(Tai_const.Create_32bit(
  4292. tprocdef(proc.def)._class.vmtmethodoffset(tprocdef(proc.def).extnumber)));
  4293. typvalue:=2;
  4294. end;
  4295. end;
  4296. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4297. end;
  4298. begin
  4299. if needs_prop_entry(tsym(sym)) then
  4300. case tsym(sym).typ of
  4301. varsym:
  4302. begin
  4303. {$ifdef dummy}
  4304. if not(tvarsym(sym).vartype.def.deftype=objectdef) or
  4305. not(tobjectdef(tvarsym(sym).vartype.def).is_class) then
  4306. internalerror(1509992);
  4307. { access to implicit class property as field }
  4308. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4309. rttiList.concat(Tai_const_symbol.Createname(tvarsym(sym.vartype.def.get_rtti_label)));
  4310. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4311. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4312. { per default stored }
  4313. rttiList.concat(Tai_const.Create_32bit(1));
  4314. { index as well as ... }
  4315. rttiList.concat(Tai_const.Create_32bit(0));
  4316. { default value are zero }
  4317. rttiList.concat(Tai_const.Create_32bit(0));
  4318. rttiList.concat(Tai_const.Create_16bit(count));
  4319. inc(count);
  4320. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4321. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym.realname))));
  4322. rttiList.concat(Tai_string.Create(tvarsym(sym.realname)));
  4323. {$endif dummy}
  4324. end;
  4325. propertysym:
  4326. begin
  4327. if ppo_indexed in tpropertysym(sym).propoptions then
  4328. proctypesinfo:=$40
  4329. else
  4330. proctypesinfo:=0;
  4331. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti)));
  4332. writeproc(tpropertysym(sym).readaccess,0);
  4333. writeproc(tpropertysym(sym).writeaccess,2);
  4334. { isn't it stored ? }
  4335. if not(ppo_stored in tpropertysym(sym).propoptions) then
  4336. begin
  4337. rttiList.concat(Tai_const.Create_32bit(0));
  4338. proctypesinfo:=proctypesinfo or (3 shl 4);
  4339. end
  4340. else
  4341. writeproc(tpropertysym(sym).storedaccess,4);
  4342. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  4343. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  4344. rttiList.concat(Tai_const.Create_16bit(count));
  4345. inc(count);
  4346. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4347. rttiList.concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  4348. rttiList.concat(Tai_string.Create(tpropertysym(sym).realname));
  4349. end;
  4350. else internalerror(1509992);
  4351. end;
  4352. end;
  4353. procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
  4354. begin
  4355. if needs_prop_entry(tsym(sym)) then
  4356. begin
  4357. case tsym(sym).typ of
  4358. propertysym:
  4359. tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti);
  4360. varsym:
  4361. tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(fullrtti);
  4362. else
  4363. internalerror(1509991);
  4364. end;
  4365. end;
  4366. end;
  4367. procedure tobjectdef.write_child_rtti_data(rt:trttitype);
  4368. begin
  4369. FRTTIType:=rt;
  4370. case rt of
  4371. initrtti :
  4372. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
  4373. fullrtti :
  4374. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti,nil);
  4375. else
  4376. internalerror(200108301);
  4377. end;
  4378. end;
  4379. type
  4380. tclasslistitem = class(TLinkedListItem)
  4381. index : longint;
  4382. p : tobjectdef;
  4383. end;
  4384. var
  4385. classtablelist : tlinkedlist;
  4386. tablecount : longint;
  4387. function searchclasstablelist(p : tobjectdef) : tclasslistitem;
  4388. var
  4389. hp : tclasslistitem;
  4390. begin
  4391. hp:=tclasslistitem(classtablelist.first);
  4392. while assigned(hp) do
  4393. if hp.p=p then
  4394. begin
  4395. searchclasstablelist:=hp;
  4396. exit;
  4397. end
  4398. else
  4399. hp:=tclasslistitem(hp.next);
  4400. searchclasstablelist:=nil;
  4401. end;
  4402. procedure tobjectdef.count_published_fields(sym:tnamedindexitem;arg:pointer);
  4403. var
  4404. hp : tclasslistitem;
  4405. begin
  4406. if needs_prop_entry(tsym(sym)) and
  4407. (tsym(sym).typ=varsym) then
  4408. begin
  4409. if tvarsym(sym).vartype.def.deftype<>objectdef then
  4410. internalerror(0206001);
  4411. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4412. if not(assigned(hp)) then
  4413. begin
  4414. hp:=tclasslistitem.create;
  4415. hp.p:=tobjectdef(tvarsym(sym).vartype.def);
  4416. hp.index:=tablecount;
  4417. classtablelist.concat(hp);
  4418. inc(tablecount);
  4419. end;
  4420. inc(count);
  4421. end;
  4422. end;
  4423. procedure tobjectdef.writefields(sym:tnamedindexitem;arg:pointer);
  4424. var
  4425. hp : tclasslistitem;
  4426. begin
  4427. if needs_prop_entry(tsym(sym)) and
  4428. (tsym(sym).typ=varsym) then
  4429. begin
  4430. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  4431. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4432. if not(assigned(hp)) then
  4433. internalerror(0206002);
  4434. rttiList.concat(Tai_const.Create_16bit(hp.index));
  4435. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym).realname)));
  4436. rttiList.concat(Tai_string.Create(tvarsym(sym).realname));
  4437. end;
  4438. end;
  4439. function tobjectdef.generate_field_table : tasmlabel;
  4440. var
  4441. fieldtable,
  4442. classtable : tasmlabel;
  4443. hp : tclasslistitem;
  4444. begin
  4445. classtablelist:=TLinkedList.Create;
  4446. objectlibrary.getdatalabel(fieldtable);
  4447. objectlibrary.getdatalabel(classtable);
  4448. count:=0;
  4449. tablecount:=0;
  4450. symtable.foreach({$ifdef FPC}@{$endif}count_published_fields,nil);
  4451. if (cs_create_smart in aktmoduleswitches) then
  4452. rttiList.concat(Tai_cut.Create);
  4453. rttilist.concat(tai_align.create(const_align(pointer_size)));
  4454. rttiList.concat(Tai_label.Create(fieldtable));
  4455. rttiList.concat(Tai_const.Create_16bit(count));
  4456. rttiList.concat(Tai_const_symbol.Create(classtable));
  4457. symtable.foreach({$ifdef FPC}@{$endif}writefields,nil);
  4458. { generate the class table }
  4459. rttilist.concat(tai_align.create(const_align(pointer_size)));
  4460. rttiList.concat(Tai_label.Create(classtable));
  4461. rttiList.concat(Tai_const.Create_16bit(tablecount));
  4462. hp:=tclasslistitem(classtablelist.first);
  4463. while assigned(hp) do
  4464. begin
  4465. rttiList.concat(Tai_const_symbol.Createname(tobjectdef(hp.p).vmt_mangledname));
  4466. hp:=tclasslistitem(hp.next);
  4467. end;
  4468. generate_field_table:=fieldtable;
  4469. classtablelist.free;
  4470. end;
  4471. function tobjectdef.next_free_name_index : longint;
  4472. var
  4473. i : longint;
  4474. begin
  4475. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4476. i:=childof.next_free_name_index
  4477. else
  4478. i:=0;
  4479. count:=0;
  4480. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4481. next_free_name_index:=i+count;
  4482. end;
  4483. procedure tobjectdef.write_rtti_data(rt:trttitype);
  4484. begin
  4485. case objecttype of
  4486. odt_class:
  4487. rttiList.concat(Tai_const.Create_8bit(tkclass));
  4488. odt_object:
  4489. rttiList.concat(Tai_const.Create_8bit(tkobject));
  4490. odt_interfacecom:
  4491. rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4492. odt_interfacecorba:
  4493. rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4494. else
  4495. exit;
  4496. end;
  4497. { generate the name }
  4498. rttiList.concat(Tai_const.Create_8bit(length(objrealname^)));
  4499. rttiList.concat(Tai_string.Create(objrealname^));
  4500. case rt of
  4501. initrtti :
  4502. begin
  4503. rttiList.concat(Tai_const.Create_32bit(size));
  4504. if objecttype in [odt_class,odt_object] then
  4505. begin
  4506. count:=0;
  4507. FRTTIType:=rt;
  4508. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
  4509. rttiList.concat(Tai_const.Create_32bit(count));
  4510. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
  4511. end;
  4512. end;
  4513. fullrtti :
  4514. begin
  4515. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4516. rttiList.concat(Tai_const.Create_32bit(0))
  4517. else
  4518. rttiList.concat(Tai_const_symbol.Createname(vmt_mangledname));
  4519. { write owner typeinfo }
  4520. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4521. rttiList.concat(Tai_const_symbol.Create(childof.get_rtti_label(fullrtti)))
  4522. else
  4523. rttiList.concat(Tai_const.Create_32bit(0));
  4524. { count total number of properties }
  4525. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4526. count:=childof.next_free_name_index
  4527. else
  4528. count:=0;
  4529. { write it }
  4530. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4531. rttiList.concat(Tai_const.Create_16bit(count));
  4532. { write unit name }
  4533. rttiList.concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4534. rttiList.concat(Tai_string.Create(current_module.realmodulename^));
  4535. { write published properties count }
  4536. count:=0;
  4537. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4538. rttiList.concat(Tai_const.Create_16bit(count));
  4539. { count is used to write nameindex }
  4540. { but we need an offset of the owner }
  4541. { to give each property an own slot }
  4542. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4543. count:=childof.next_free_name_index
  4544. else
  4545. count:=0;
  4546. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info,nil);
  4547. end;
  4548. end;
  4549. end;
  4550. function tobjectdef.is_publishable : boolean;
  4551. begin
  4552. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4553. end;
  4554. {****************************************************************************
  4555. TIMPLEMENTEDINTERFACES
  4556. ****************************************************************************}
  4557. type
  4558. tnamemap = class(TNamedIndexItem)
  4559. newname: pstring;
  4560. constructor create(const aname, anewname: string);
  4561. destructor destroy; override;
  4562. end;
  4563. constructor tnamemap.create(const aname, anewname: string);
  4564. begin
  4565. inherited createname(name);
  4566. newname:=stringdup(anewname);
  4567. end;
  4568. destructor tnamemap.destroy;
  4569. begin
  4570. stringdispose(newname);
  4571. inherited destroy;
  4572. end;
  4573. type
  4574. tprocdefstore = class(TNamedIndexItem)
  4575. procdef: tprocdef;
  4576. constructor create(aprocdef: tprocdef);
  4577. end;
  4578. constructor tprocdefstore.create(aprocdef: tprocdef);
  4579. begin
  4580. inherited create;
  4581. procdef:=aprocdef;
  4582. end;
  4583. type
  4584. timplintfentry = class(TNamedIndexItem)
  4585. intf: tobjectdef;
  4586. ioffs: longint;
  4587. namemappings: tdictionary;
  4588. procdefs: TIndexArray;
  4589. constructor create(aintf: tobjectdef);
  4590. destructor destroy; override;
  4591. end;
  4592. constructor timplintfentry.create(aintf: tobjectdef);
  4593. begin
  4594. inherited create;
  4595. intf:=aintf;
  4596. ioffs:=-1;
  4597. namemappings:=nil;
  4598. procdefs:=nil;
  4599. end;
  4600. destructor timplintfentry.destroy;
  4601. begin
  4602. if assigned(namemappings) then
  4603. namemappings.free;
  4604. if assigned(procdefs) then
  4605. procdefs.free;
  4606. inherited destroy;
  4607. end;
  4608. constructor timplementedinterfaces.create;
  4609. begin
  4610. finterfaces:=tindexarray.create(1);
  4611. end;
  4612. destructor timplementedinterfaces.destroy;
  4613. begin
  4614. finterfaces.destroy;
  4615. end;
  4616. function timplementedinterfaces.count: longint;
  4617. begin
  4618. count:=finterfaces.count;
  4619. end;
  4620. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4621. begin
  4622. if (intfindex<1) or (intfindex>count) then
  4623. InternalError(200006123);
  4624. end;
  4625. function timplementedinterfaces.interfaces(intfindex: longint): tobjectdef;
  4626. begin
  4627. checkindex(intfindex);
  4628. interfaces:=timplintfentry(finterfaces.search(intfindex)).intf;
  4629. end;
  4630. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4631. begin
  4632. checkindex(intfindex);
  4633. ioffsets:=@timplintfentry(finterfaces.search(intfindex)).ioffs;
  4634. end;
  4635. function timplementedinterfaces.searchintf(def: tdef): longint;
  4636. var
  4637. i: longint;
  4638. begin
  4639. i:=1;
  4640. while (i<=count) and (tdef(interfaces(i))<>def) do inc(i);
  4641. if i<=count then
  4642. searchintf:=i
  4643. else
  4644. searchintf:=-1;
  4645. end;
  4646. procedure timplementedinterfaces.deref;
  4647. var
  4648. i: longint;
  4649. begin
  4650. for i:=1 to count do
  4651. with timplintfentry(finterfaces.search(i)) do
  4652. resolvedef(pointer(intf));
  4653. end;
  4654. procedure timplementedinterfaces.addintfref(def: pointer);
  4655. begin
  4656. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4657. end;
  4658. procedure timplementedinterfaces.addintf(def: tdef);
  4659. begin
  4660. if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or
  4661. not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4662. internalerror(200006124);
  4663. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4664. end;
  4665. procedure timplementedinterfaces.clearmappings;
  4666. var
  4667. i: longint;
  4668. begin
  4669. for i:=1 to count do
  4670. with timplintfentry(finterfaces.search(i)) do
  4671. begin
  4672. if assigned(namemappings) then
  4673. namemappings.free;
  4674. namemappings:=nil;
  4675. end;
  4676. end;
  4677. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4678. begin
  4679. checkindex(intfindex);
  4680. with timplintfentry(finterfaces.search(intfindex)) do
  4681. begin
  4682. if not assigned(namemappings) then
  4683. namemappings:=tdictionary.create;
  4684. namemappings.insert(tnamemap.create(name,newname));
  4685. end;
  4686. end;
  4687. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4688. begin
  4689. checkindex(intfindex);
  4690. if not assigned(nextexist) then
  4691. with timplintfentry(finterfaces.search(intfindex)) do
  4692. begin
  4693. if assigned(namemappings) then
  4694. nextexist:=namemappings.search(name)
  4695. else
  4696. nextexist:=nil;
  4697. end;
  4698. if assigned(nextexist) then
  4699. begin
  4700. getmappings:=tnamemap(nextexist).newname^;
  4701. nextexist:=tnamemap(nextexist).listnext;
  4702. end
  4703. else
  4704. getmappings:='';
  4705. end;
  4706. procedure timplementedinterfaces.clearimplprocs;
  4707. var
  4708. i: longint;
  4709. begin
  4710. for i:=1 to count do
  4711. with timplintfentry(finterfaces.search(i)) do
  4712. begin
  4713. if assigned(procdefs) then
  4714. procdefs.free;
  4715. procdefs:=nil;
  4716. end;
  4717. end;
  4718. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef);
  4719. begin
  4720. checkindex(intfindex);
  4721. with timplintfentry(finterfaces.search(intfindex)) do
  4722. begin
  4723. if not assigned(procdefs) then
  4724. procdefs:=tindexarray.create(4);
  4725. procdefs.insert(tprocdefstore.create(procdef));
  4726. end;
  4727. end;
  4728. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4729. begin
  4730. checkindex(intfindex);
  4731. with timplintfentry(finterfaces.search(intfindex)) do
  4732. if assigned(procdefs) then
  4733. implproccount:=procdefs.count
  4734. else
  4735. implproccount:=0;
  4736. end;
  4737. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef;
  4738. begin
  4739. checkindex(intfindex);
  4740. with timplintfentry(finterfaces.search(intfindex)) do
  4741. if assigned(procdefs) then
  4742. implprocs:=tprocdefstore(procdefs.search(procindex)).procdef
  4743. else
  4744. internalerror(200006131);
  4745. end;
  4746. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4747. var
  4748. possible: boolean;
  4749. i: longint;
  4750. iiep1: TIndexArray;
  4751. iiep2: TIndexArray;
  4752. begin
  4753. checkindex(intfindex);
  4754. checkindex(remainindex);
  4755. iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs;
  4756. iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs;
  4757. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4758. begin
  4759. possible:=true;
  4760. weight:=0;
  4761. end
  4762. else
  4763. begin
  4764. possible:=assigned(iiep2) and (iiep1.count<=iiep2.count);
  4765. i:=1;
  4766. while (possible) and (i<=iiep1.count) do
  4767. begin
  4768. possible:=
  4769. (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef);
  4770. inc(i);
  4771. end;
  4772. if possible then
  4773. weight:=iiep1.count;
  4774. end;
  4775. isimplmergepossible:=possible;
  4776. end;
  4777. {****************************************************************************
  4778. TFORWARDDEF
  4779. ****************************************************************************}
  4780. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  4781. var
  4782. oldregisterdef : boolean;
  4783. begin
  4784. { never register the forwarddefs, they are disposed at the
  4785. end of the type declaration block }
  4786. oldregisterdef:=registerdef;
  4787. registerdef:=false;
  4788. inherited create;
  4789. registerdef:=oldregisterdef;
  4790. deftype:=forwarddef;
  4791. tosymname:=stringdup(s);
  4792. forwardpos:=pos;
  4793. end;
  4794. function tforwarddef.gettypename:string;
  4795. begin
  4796. gettypename:='unresolved forward to '+tosymname^;
  4797. end;
  4798. destructor tforwarddef.destroy;
  4799. begin
  4800. if assigned(tosymname) then
  4801. stringdispose(tosymname);
  4802. inherited destroy;
  4803. end;
  4804. {****************************************************************************
  4805. TERRORDEF
  4806. ****************************************************************************}
  4807. constructor terrordef.create;
  4808. begin
  4809. inherited create;
  4810. deftype:=errordef;
  4811. end;
  4812. {$ifdef GDB}
  4813. function terrordef.stabstring : pchar;
  4814. begin
  4815. stabstring:=strpnew('error'+numberstring);
  4816. end;
  4817. procedure terrordef.concatstabto(asmlist : taasmoutput);
  4818. begin
  4819. internalerror(20021119);
  4820. end;
  4821. {$endif GDB}
  4822. function terrordef.gettypename:string;
  4823. begin
  4824. gettypename:='<erroneous type>';
  4825. end;
  4826. function terrordef.getmangledparaname:string;
  4827. begin
  4828. getmangledparaname:='error';
  4829. end;
  4830. {****************************************************************************
  4831. GDB Helpers
  4832. ****************************************************************************}
  4833. {$ifdef GDB}
  4834. function typeglobalnumber(const s : string) : string;
  4835. var st : string;
  4836. symt : tsymtable;
  4837. srsym : tsym;
  4838. srsymtable : tsymtable;
  4839. old_make_ref : boolean;
  4840. begin
  4841. old_make_ref:=make_ref;
  4842. make_ref:=false;
  4843. typeglobalnumber := '0';
  4844. srsym := nil;
  4845. if pos('.',s) > 0 then
  4846. begin
  4847. st := copy(s,1,pos('.',s)-1);
  4848. searchsym(st,srsym,srsymtable);
  4849. st := copy(s,pos('.',s)+1,255);
  4850. if assigned(srsym) then
  4851. begin
  4852. if srsym.typ = unitsym then
  4853. begin
  4854. symt := tunitsym(srsym).unitsymtable;
  4855. srsym := tsym(symt.search(st));
  4856. end else srsym := nil;
  4857. end;
  4858. end else st := s;
  4859. if srsym = nil then
  4860. searchsym(st,srsym,srsymtable);
  4861. if (srsym=nil) or
  4862. (srsym.typ<>typesym) then
  4863. begin
  4864. Message(type_e_type_id_expected);
  4865. exit;
  4866. end;
  4867. typeglobalnumber := tstoreddef(ttypesym(srsym).restype.def).numberstring;
  4868. make_ref:=old_make_ref;
  4869. end;
  4870. {$endif GDB}
  4871. {****************************************************************************
  4872. Definition Helpers
  4873. ****************************************************************************}
  4874. procedure reset_global_defs;
  4875. var
  4876. def : tstoreddef;
  4877. {$ifdef debug}
  4878. prevdef : tstoreddef;
  4879. {$endif debug}
  4880. begin
  4881. {$ifdef debug}
  4882. prevdef:=nil;
  4883. {$endif debug}
  4884. {$ifdef GDB}
  4885. pglobaltypecount:=@globaltypecount;
  4886. {$endif GDB}
  4887. def:=firstglobaldef;
  4888. while assigned(def) do
  4889. begin
  4890. {$ifdef GDB}
  4891. if assigned(def.typesym) then
  4892. ttypesym(def.typesym).isusedinstab:=false;
  4893. def.is_def_stab_written:=not_written;
  4894. {$endif GDB}
  4895. if assigned(def.rttitablesym) then
  4896. trttisym(def.rttitablesym).lab := nil;
  4897. if assigned(def.inittablesym) then
  4898. trttisym(def.inittablesym).lab := nil;
  4899. def.localrttilab[initrtti]:=nil;
  4900. def.localrttilab[fullrtti]:=nil;
  4901. {$ifdef debug}
  4902. prevdef:=def;
  4903. {$endif debug}
  4904. def:=def.nextglobal;
  4905. end;
  4906. end;
  4907. function is_interfacecom(def: tdef): boolean;
  4908. begin
  4909. is_interfacecom:=
  4910. assigned(def) and
  4911. (def.deftype=objectdef) and
  4912. (tobjectdef(def).objecttype=odt_interfacecom);
  4913. end;
  4914. function is_interfacecorba(def: tdef): boolean;
  4915. begin
  4916. is_interfacecorba:=
  4917. assigned(def) and
  4918. (def.deftype=objectdef) and
  4919. (tobjectdef(def).objecttype=odt_interfacecorba);
  4920. end;
  4921. function is_interface(def: tdef): boolean;
  4922. begin
  4923. is_interface:=
  4924. assigned(def) and
  4925. (def.deftype=objectdef) and
  4926. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  4927. end;
  4928. function is_class(def: tdef): boolean;
  4929. begin
  4930. is_class:=
  4931. assigned(def) and
  4932. (def.deftype=objectdef) and
  4933. (tobjectdef(def).objecttype=odt_class);
  4934. end;
  4935. function is_object(def: tdef): boolean;
  4936. begin
  4937. is_object:=
  4938. assigned(def) and
  4939. (def.deftype=objectdef) and
  4940. (tobjectdef(def).objecttype=odt_object);
  4941. end;
  4942. function is_cppclass(def: tdef): boolean;
  4943. begin
  4944. is_cppclass:=
  4945. assigned(def) and
  4946. (def.deftype=objectdef) and
  4947. (tobjectdef(def).objecttype=odt_cppclass);
  4948. end;
  4949. function is_class_or_interface(def: tdef): boolean;
  4950. begin
  4951. is_class_or_interface:=
  4952. assigned(def) and
  4953. (def.deftype=objectdef) and
  4954. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4955. end;
  4956. end.
  4957. {
  4958. $Log$
  4959. Revision 1.129 2003-02-19 22:00:14 daniel
  4960. * Code generator converted to new register notation
  4961. - Horribily outdated todo.txt removed
  4962. Revision 1.128 2003/02/02 19:25:54 carl
  4963. * Several bugfixes for m68k target (register alloc., opcode emission)
  4964. + VIS target
  4965. + Generic add more complete (still not verified)
  4966. Revision 1.127 2003/01/21 14:36:44 pierre
  4967. * set sizes needs to be passes in bits not bytes to stabs info
  4968. Revision 1.126 2003/01/16 22:11:33 peter
  4969. * fixed tprocdef.is_addressonly
  4970. Revision 1.125 2003/01/15 01:44:33 peter
  4971. * merged methodpointer fixes from 1.0.x
  4972. Revision 1.124 2003/01/09 21:52:37 peter
  4973. * merged some verbosity options.
  4974. * V_LineInfo is a verbosity flag to include line info
  4975. Revision 1.123 2003/01/06 21:16:52 peter
  4976. * po_addressonly added to retrieve the address of a methodpointer
  4977. only, this is used for @tclass.method which has no self pointer
  4978. Revision 1.122 2003/01/05 15:54:15 florian
  4979. + added proper support of type = type <type>; for simple types
  4980. Revision 1.121 2003/01/05 13:36:53 florian
  4981. * x86-64 compiles
  4982. + very basic support for float128 type (x86-64 only)
  4983. Revision 1.120 2003/01/02 19:49:00 peter
  4984. * update self parameter only for methodpointer and methods
  4985. Revision 1.119 2002/12/29 18:25:59 peter
  4986. * tprocdef.gettypename implemented
  4987. Revision 1.118 2002/12/27 15:23:09 peter
  4988. * write class methods in fullname
  4989. Revision 1.117 2002/12/15 19:34:31 florian
  4990. + some front end stuff for vs_hidden added
  4991. Revision 1.116 2002/12/15 11:26:02 peter
  4992. * ignore vs_hidden parameters when choosing overloaded proc
  4993. Revision 1.115 2002/12/07 14:27:09 carl
  4994. * 3% memory optimization
  4995. * changed some types
  4996. + added type checking with different size for call node and for
  4997. parameters
  4998. Revision 1.114 2002/12/01 22:05:27 carl
  4999. * no more warnings for structures over 32K since this is
  5000. handled correctly in this version of the compiler.
  5001. Revision 1.113 2002/11/27 20:04:09 peter
  5002. * tvarsym.get_push_size replaced by paramanager.push_size
  5003. Revision 1.112 2002/11/25 21:05:53 carl
  5004. * several mistakes fixed in message files
  5005. Revision 1.111 2002/11/25 18:43:33 carl
  5006. - removed the invalid if <> checking (Delphi is strange on this)
  5007. + implemented abstract warning on instance creation of class with
  5008. abstract methods.
  5009. * some error message cleanups
  5010. Revision 1.110 2002/11/25 17:43:24 peter
  5011. * splitted defbase in defutil,symutil,defcmp
  5012. * merged isconvertable and is_equal into compare_defs(_ext)
  5013. * made operator search faster by walking the list only once
  5014. Revision 1.109 2002/11/23 22:50:06 carl
  5015. * some small speed optimizations
  5016. + added several new warnings/hints
  5017. Revision 1.108 2002/11/22 22:48:10 carl
  5018. * memory optimization with tconstsym (1.5%)
  5019. Revision 1.107 2002/11/19 16:21:29 pierre
  5020. * correct several stabs generation problems
  5021. Revision 1.106 2002/11/18 17:31:59 peter
  5022. * pass proccalloption to ret_in_xxx and push_xxx functions
  5023. Revision 1.105 2002/11/17 16:31:57 carl
  5024. * memory optimization (3-4%) : cleanup of tai fields,
  5025. cleanup of tdef and tsym fields.
  5026. * make it work for m68k
  5027. Revision 1.104 2002/11/16 19:53:18 carl
  5028. * avoid Range check errors
  5029. Revision 1.103 2002/11/15 16:29:09 peter
  5030. * fixed rtti for int64 (merged)
  5031. Revision 1.102 2002/11/15 01:58:54 peter
  5032. * merged changes from 1.0.7 up to 04-11
  5033. - -V option for generating bug report tracing
  5034. - more tracing for option parsing
  5035. - errors for cdecl and high()
  5036. - win32 import stabs
  5037. - win32 records<=8 are returned in eax:edx (turned off by default)
  5038. - heaptrc update
  5039. - more info for temp management in .s file with EXTDEBUG
  5040. Revision 1.101 2002/11/09 15:31:02 carl
  5041. + align RTTI tables
  5042. Revision 1.100 2002/10/19 15:09:25 peter
  5043. + tobjectdef.members_need_inittable that is used to generate only the
  5044. inittable when it is really used. This saves a lot of useless calls
  5045. to fpc_finalize when destroying classes
  5046. Revision 1.99 2002/10/07 21:30:27 peter
  5047. * removed obsolete rangecheck stuff
  5048. Revision 1.98 2002/10/05 15:14:26 peter
  5049. * getparamangeldname for errordef
  5050. Revision 1.97 2002/10/05 12:43:28 carl
  5051. * fixes for Delphi 6 compilation
  5052. (warning : Some features do not work under Delphi)
  5053. Revision 1.96 2002/09/27 21:13:29 carl
  5054. * low-highval always checked if limit ober 2GB is reached (to avoid overflow)
  5055. Revision 1.95 2002/09/16 09:31:10 florian
  5056. * fixed currency size
  5057. Revision 1.94 2002/09/09 17:34:15 peter
  5058. * tdicationary.replace added to replace and item in a dictionary. This
  5059. is only allowed for the same name
  5060. * varsyms are inserted in symtable before the types are parsed. This
  5061. fixes the long standing "var longint : longint" bug
  5062. - consume_idlist and idstringlist removed. The loops are inserted
  5063. at the callers place and uses the symtable for duplicate id checking
  5064. Revision 1.93 2002/09/07 15:25:07 peter
  5065. * old logs removed and tabs fixed
  5066. Revision 1.92 2002/09/05 19:29:42 peter
  5067. * memdebug enhancements
  5068. Revision 1.91 2002/08/25 19:25:20 peter
  5069. * sym.insert_in_data removed
  5070. * symtable.insertvardata/insertconstdata added
  5071. * removed insert_in_data call from symtable.insert, it needs to be
  5072. called separatly. This allows to deref the address calculation
  5073. * procedures now calculate the parast addresses after the procedure
  5074. directives are parsed. This fixes the cdecl parast problem
  5075. * push_addr_param has an extra argument that specifies if cdecl is used
  5076. or not
  5077. Revision 1.90 2002/08/18 20:06:25 peter
  5078. * inlining is now also allowed in interface
  5079. * renamed write/load to ppuwrite/ppuload
  5080. * tnode storing in ppu
  5081. * nld,ncon,nbas are already updated for storing in ppu
  5082. Revision 1.89 2002/08/11 15:28:00 florian
  5083. + support of explicit type case <any ordinal type>->pointer
  5084. (delphi mode only)
  5085. Revision 1.88 2002/08/11 14:32:28 peter
  5086. * renamed current_library to objectlibrary
  5087. Revision 1.87 2002/08/11 13:24:13 peter
  5088. * saving of asmsymbols in ppu supported
  5089. * asmsymbollist global is removed and moved into a new class
  5090. tasmlibrarydata that will hold the info of a .a file which
  5091. corresponds with a single module. Added librarydata to tmodule
  5092. to keep the library info stored for the module. In the future the
  5093. objectfiles will also be stored to the tasmlibrarydata class
  5094. * all getlabel/newasmsymbol and friends are moved to the new class
  5095. Revision 1.86 2002/08/09 07:33:03 florian
  5096. * a couple of interface related fixes
  5097. Revision 1.85 2002/07/23 09:51:24 daniel
  5098. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  5099. are worth comitting.
  5100. Revision 1.84 2002/07/20 11:57:57 florian
  5101. * types.pas renamed to defbase.pas because D6 contains a types
  5102. unit so this would conflicts if D6 programms are compiled
  5103. + Willamette/SSE2 instructions to assembler added
  5104. Revision 1.83 2002/07/11 14:41:30 florian
  5105. * start of the new generic parameter handling
  5106. Revision 1.82 2002/07/07 09:52:32 florian
  5107. * powerpc target fixed, very simple units can be compiled
  5108. * some basic stuff for better callparanode handling, far from being finished
  5109. Revision 1.81 2002/07/01 18:46:26 peter
  5110. * internal linker
  5111. * reorganized aasm layer
  5112. Revision 1.80 2002/07/01 16:23:54 peter
  5113. * cg64 patch
  5114. * basics for currency
  5115. * asnode updates for class and interface (not finished)
  5116. Revision 1.79 2002/05/18 13:34:18 peter
  5117. * readded missing revisions
  5118. Revision 1.78 2002/05/16 19:46:44 carl
  5119. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  5120. + try to fix temp allocation (still in ifdef)
  5121. + generic constructor calls
  5122. + start of tassembler / tmodulebase class cleanup
  5123. Revision 1.76 2002/05/12 16:53:10 peter
  5124. * moved entry and exitcode to ncgutil and cgobj
  5125. * foreach gets extra argument for passing local data to the
  5126. iterator function
  5127. * -CR checks also class typecasts at runtime by changing them
  5128. into as
  5129. * fixed compiler to cycle with the -CR option
  5130. * fixed stabs with elf writer, finally the global variables can
  5131. be watched
  5132. * removed a lot of routines from cga unit and replaced them by
  5133. calls to cgobj
  5134. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  5135. u32bit then the other is typecasted also to u32bit without giving
  5136. a rangecheck warning/error.
  5137. * fixed pascal calling method with reversing also the high tree in
  5138. the parast, detected by tcalcst3 test
  5139. Revision 1.75 2002/04/25 20:16:39 peter
  5140. * moved more routines from cga/n386util
  5141. Revision 1.74 2002/04/23 19:16:35 peter
  5142. * add pinline unit that inserts compiler supported functions using
  5143. one or more statements
  5144. * moved finalize and setlength from ninl to pinline
  5145. Revision 1.73 2002/04/21 19:02:05 peter
  5146. * removed newn and disposen nodes, the code is now directly
  5147. inlined from pexpr
  5148. * -an option that will write the secondpass nodes to the .s file, this
  5149. requires EXTDEBUG define to actually write the info
  5150. * fixed various internal errors and crashes due recent code changes
  5151. Revision 1.72 2002/04/20 21:32:25 carl
  5152. + generic FPC_CHECKPOINTER
  5153. + first parameter offset in stack now portable
  5154. * rename some constants
  5155. + move some cpu stuff to other units
  5156. - remove unused constents
  5157. * fix stacksize for some targets
  5158. * fix generic size problems which depend now on EXTEND_SIZE constant
  5159. }