symdef.pas 172 KB

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