symdef.pas 172 KB

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