symdef.pas 171 KB

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