symdef.pas 166 KB

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