symdef.pas 175 KB

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