symdef.pas 168 KB

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