symdef.pas 172 KB

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