symdef.pas 168 KB

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