symdef.pas 172 KB

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