symdef.pas 151 KB

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