symdef.pas 139 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692
  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. cclasses,
  23. { global }
  24. globtype,globals,tokens,constexp,
  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 }
  42. tstoreddef = class(tdef)
  43. protected
  44. typesymderef : tderef;
  45. public
  46. {$ifdef EXTDEBUG}
  47. fileinfo : tfileposinfo;
  48. {$endif}
  49. { generic support }
  50. genericdef : tstoreddef;
  51. genericdefderef : tderef;
  52. generictokenbuf : tdynamicarray;
  53. constructor create(dt:tdeftyp);
  54. constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  55. destructor destroy;override;
  56. procedure reset;virtual;
  57. function getcopy : tstoreddef;virtual;
  58. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  59. procedure buildderef;override;
  60. procedure buildderefimpl;override;
  61. procedure deref;override;
  62. procedure derefimpl;override;
  63. function size:aint;override;
  64. function getvardef:longint;override;
  65. function alignment:shortint;override;
  66. function is_publishable : boolean;override;
  67. function needs_inittable : boolean;override;
  68. function rtti_mangledname(rt:trttitype):string;override;
  69. { regvars }
  70. function is_intregable : boolean;
  71. function is_fpuregable : boolean;
  72. { generics }
  73. procedure initgeneric;
  74. private
  75. savesize : aint;
  76. end;
  77. tfiletyp = (ft_text,ft_typed,ft_untyped);
  78. tfiledef = class(tstoreddef)
  79. filetyp : tfiletyp;
  80. typedfiledef : tdef;
  81. typedfiledefderef : tderef;
  82. constructor createtext;
  83. constructor createuntyped;
  84. constructor createtyped(def : tdef);
  85. constructor ppuload(ppufile:tcompilerppufile);
  86. function getcopy : tstoreddef;override;
  87. procedure ppuwrite(ppufile:tcompilerppufile);override;
  88. procedure buildderef;override;
  89. procedure deref;override;
  90. function GetTypeName:string;override;
  91. function getmangledparaname:string;override;
  92. procedure setsize;
  93. end;
  94. tvariantdef = class(tstoreddef)
  95. varianttype : tvarianttype;
  96. constructor create(v : tvarianttype);
  97. constructor ppuload(ppufile:tcompilerppufile);
  98. function getcopy : tstoreddef;override;
  99. function GetTypeName:string;override;
  100. procedure ppuwrite(ppufile:tcompilerppufile);override;
  101. function getvardef:longint;override;
  102. procedure setsize;
  103. function is_publishable : boolean;override;
  104. function needs_inittable : boolean;override;
  105. end;
  106. tformaldef = class(tstoreddef)
  107. typed:boolean;
  108. constructor create(Atyped:boolean);
  109. constructor ppuload(ppufile:tcompilerppufile);
  110. procedure ppuwrite(ppufile:tcompilerppufile);override;
  111. function GetTypeName:string;override;
  112. end;
  113. tforwarddef = class(tstoreddef)
  114. tosymname : pshortstring;
  115. forwardpos : tfileposinfo;
  116. constructor create(const s:string;const pos : tfileposinfo);
  117. destructor destroy;override;
  118. function GetTypeName:string;override;
  119. end;
  120. tundefineddef = class(tstoreddef)
  121. constructor create;
  122. constructor ppuload(ppufile:tcompilerppufile);
  123. procedure ppuwrite(ppufile:tcompilerppufile);override;
  124. function GetTypeName:string;override;
  125. end;
  126. terrordef = class(tstoreddef)
  127. constructor create;
  128. procedure ppuwrite(ppufile:tcompilerppufile);override;
  129. function GetTypeName:string;override;
  130. function getmangledparaname : string;override;
  131. end;
  132. tabstractpointerdef = class(tstoreddef)
  133. pointeddef : tdef;
  134. pointeddefderef : tderef;
  135. constructor create(dt:tdeftyp;def:tdef);
  136. constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  137. procedure ppuwrite(ppufile:tcompilerppufile);override;
  138. procedure buildderef;override;
  139. procedure deref;override;
  140. end;
  141. tpointerdef = class(tabstractpointerdef)
  142. is_far : boolean;
  143. constructor create(def:tdef);
  144. constructor createfar(def:tdef);
  145. function getcopy : tstoreddef;override;
  146. constructor ppuload(ppufile:tcompilerppufile);
  147. procedure ppuwrite(ppufile:tcompilerppufile);override;
  148. function GetTypeName:string;override;
  149. end;
  150. tabstractrecorddef= class(tstoreddef)
  151. symtable : TSymtable;
  152. cloneddef : tabstractrecorddef;
  153. cloneddefderef : tderef;
  154. procedure reset;override;
  155. function GetSymtable(t:tGetSymtable):TSymtable;override;
  156. function is_packed:boolean;
  157. end;
  158. trecorddef = class(tabstractrecorddef)
  159. public
  160. isunion : boolean;
  161. constructor create(p : TSymtable);
  162. constructor ppuload(ppufile:tcompilerppufile);
  163. destructor destroy;override;
  164. function getcopy : tstoreddef;override;
  165. procedure ppuwrite(ppufile:tcompilerppufile);override;
  166. procedure buildderef;override;
  167. procedure deref;override;
  168. function size:aint;override;
  169. function alignment : shortint;override;
  170. function padalignment: shortint;
  171. function GetTypeName:string;override;
  172. { debug }
  173. function needs_inittable : boolean;override;
  174. end;
  175. tprocdef = class;
  176. tobjectdef = class;
  177. { TImplementedInterface }
  178. TImplementedInterface = class
  179. IntfDef : tobjectdef;
  180. IntfDefDeref : tderef;
  181. IType : tinterfaceentrytype;
  182. IOffset : longint;
  183. VtblImplIntf : TImplementedInterface;
  184. NameMappings : TFPHashList;
  185. ProcDefs : TFPObjectList;
  186. ImplementsGetter : tsym;
  187. constructor create(aintf: tobjectdef);
  188. constructor create_deref(d:tderef);
  189. destructor destroy; override;
  190. function getcopy:TImplementedInterface;
  191. procedure buildderef;
  192. procedure deref;
  193. procedure AddMapping(const origname, newname: string);
  194. function GetMapping(const origname: string):string;
  195. procedure AddImplProc(pd:tprocdef);
  196. function IsImplMergePossible(MergingIntf:TImplementedInterface;out weight: longint): boolean;
  197. end;
  198. { tvmtentry }
  199. tvmtentry = record
  200. procdef : tprocdef;
  201. procdefderef : tderef;
  202. visibility : tvisibility;
  203. end;
  204. pvmtentry = ^tvmtentry;
  205. { tobjectdef }
  206. tvmcallstatic = (vmcs_default, vmcs_yes, vmcs_no, vmcs_unreachable);
  207. pmvcallstaticinfo = ^tmvcallstaticinfo;
  208. tmvcallstaticinfo = array[0..1024*1024-1] of tvmcallstatic;
  209. tobjectdef = class(tabstractrecorddef)
  210. public
  211. dwarf_struct_lab : tasmsymbol;
  212. childof : tobjectdef;
  213. childofderef : tderef;
  214. objname,
  215. objrealname : pshortstring;
  216. objectoptions : tobjectoptions;
  217. { to be able to have a variable vmt position }
  218. { and no vmt field for objects without virtuals }
  219. vmtentries : TFPList;
  220. vmcallstaticinfo : pmvcallstaticinfo;
  221. vmt_offset : longint;
  222. objecttype : tobjecttyp;
  223. iidguid : pguid;
  224. iidstr : pshortstring;
  225. writing_class_record_dbginfo,
  226. { a class of this type has been created in this module }
  227. created_in_current_module,
  228. { a loadvmtnode for this class has been created in this
  229. module, so if a classrefdef variable of this or a parent
  230. class is used somewhere to instantiate a class, then this
  231. class may be instantiated
  232. }
  233. maybe_created_in_current_module,
  234. { a "class of" this particular class has been created in
  235. this module
  236. }
  237. classref_created_in_current_module : boolean;
  238. { store implemented interfaces defs and name mappings }
  239. ImplementedInterfaces : TFPObjectList;
  240. constructor create(ot : tobjecttyp;const n : string;c : tobjectdef);
  241. constructor ppuload(ppufile:tcompilerppufile);
  242. destructor destroy;override;
  243. function getcopy : tstoreddef;override;
  244. procedure ppuwrite(ppufile:tcompilerppufile);override;
  245. function GetTypeName:string;override;
  246. procedure buildderef;override;
  247. procedure deref;override;
  248. procedure buildderefimpl;override;
  249. procedure derefimpl;override;
  250. procedure resetvmtentries;
  251. procedure copyvmtentries(objdef:tobjectdef);
  252. function getparentdef:tdef;override;
  253. function size : aint;override;
  254. function alignment:shortint;override;
  255. function vmtmethodoffset(index:longint):longint;
  256. function members_need_inittable : boolean;
  257. function find_implemented_interface(aintfdef:tobjectdef):TImplementedInterface;
  258. { this should be called when this class implements an interface }
  259. procedure prepareguid;
  260. function is_publishable : boolean;override;
  261. function needs_inittable : boolean;override;
  262. function vmt_mangledname : string;
  263. procedure check_forwards;
  264. function is_related(d : tdef) : boolean;override;
  265. procedure insertvmt;
  266. procedure set_parent(c : tobjectdef);
  267. function FindDestructor : tprocdef;
  268. function implements_any_interfaces: boolean;
  269. procedure reset; override;
  270. { WPO }
  271. procedure register_created_object_type;override;
  272. procedure register_maybe_created_object_type;
  273. procedure register_created_classref_type;
  274. procedure register_vmt_call(index:longint);
  275. procedure make_all_methods_external;
  276. end;
  277. tclassrefdef = class(tabstractpointerdef)
  278. constructor create(def:tdef);
  279. constructor ppuload(ppufile:tcompilerppufile);
  280. procedure ppuwrite(ppufile:tcompilerppufile);override;
  281. function GetTypeName:string;override;
  282. function is_publishable : boolean;override;
  283. procedure register_created_object_type;override;
  284. procedure reset;override;
  285. end;
  286. tarraydef = class(tstoreddef)
  287. lowrange,
  288. highrange : aint;
  289. rangedef : tdef;
  290. rangedefderef : tderef;
  291. arrayoptions : tarraydefoptions;
  292. protected
  293. _elementdef : tdef;
  294. _elementdefderef : tderef;
  295. procedure setelementdef(def:tdef);
  296. public
  297. function elesize : aint;
  298. function elepackedbitsize : aint;
  299. function elecount : aword;
  300. constructor create_from_pointer(def:tdef);
  301. constructor create(l,h : aint;def:tdef);
  302. constructor ppuload(ppufile:tcompilerppufile);
  303. function getcopy : tstoreddef;override;
  304. procedure ppuwrite(ppufile:tcompilerppufile);override;
  305. function GetTypeName:string;override;
  306. function getmangledparaname : string;override;
  307. procedure buildderef;override;
  308. procedure deref;override;
  309. function size : aint;override;
  310. function alignment : shortint;override;
  311. { returns the label of the range check string }
  312. function needs_inittable : boolean;override;
  313. property elementdef : tdef read _elementdef write setelementdef;
  314. function is_publishable : boolean;override;
  315. end;
  316. torddef = class(tstoreddef)
  317. low,high : TConstExprInt;
  318. ordtype : tordtype;
  319. constructor create(t : tordtype;v,b : TConstExprInt);
  320. constructor ppuload(ppufile:tcompilerppufile);
  321. function getcopy : tstoreddef;override;
  322. procedure ppuwrite(ppufile:tcompilerppufile);override;
  323. function is_publishable : boolean;override;
  324. function GetTypeName:string;override;
  325. function alignment:shortint;override;
  326. procedure setsize;
  327. function packedbitsize: aint; override;
  328. function getvardef : longint;override;
  329. end;
  330. tfloatdef = class(tstoreddef)
  331. floattype : tfloattype;
  332. constructor create(t : tfloattype);
  333. constructor ppuload(ppufile:tcompilerppufile);
  334. function getcopy : tstoreddef;override;
  335. procedure ppuwrite(ppufile:tcompilerppufile);override;
  336. function GetTypeName:string;override;
  337. function is_publishable : boolean;override;
  338. function alignment:shortint;override;
  339. procedure setsize;
  340. function getvardef:longint;override;
  341. end;
  342. tabstractprocdef = class(tstoreddef)
  343. { saves a definition to the return type }
  344. returndef : tdef;
  345. returndefderef : tderef;
  346. parast : TSymtable;
  347. paras : tparalist;
  348. proctypeoption : tproctypeoption;
  349. proccalloption : tproccalloption;
  350. procoptions : tprocoptions;
  351. requiredargarea : aint;
  352. { number of user visibile parameters }
  353. maxparacount,
  354. minparacount : byte;
  355. {$ifdef m68k}
  356. exp_funcretloc : tregister; { explicit funcretloc for AmigaOS }
  357. {$endif}
  358. funcretloc : array[tcallercallee] of TLocation;
  359. has_paraloc_info : boolean; { paraloc info is available }
  360. constructor create(dt:tdeftyp;level:byte);
  361. constructor ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  362. destructor destroy;override;
  363. procedure ppuwrite(ppufile:tcompilerppufile);override;
  364. procedure buildderef;override;
  365. procedure deref;override;
  366. procedure calcparas;
  367. function typename_paras(showhidden:boolean): string;
  368. function is_methodpointer:boolean;virtual;
  369. function is_addressonly:boolean;virtual;
  370. private
  371. procedure count_para(p:TObject;arg:pointer);
  372. procedure insert_para(p:TObject;arg:pointer);
  373. end;
  374. tprocvardef = class(tabstractprocdef)
  375. constructor create(level:byte);
  376. constructor ppuload(ppufile:tcompilerppufile);
  377. function getcopy : tstoreddef;override;
  378. procedure ppuwrite(ppufile:tcompilerppufile);override;
  379. function GetSymtable(t:tGetSymtable):TSymtable;override;
  380. function size : aint;override;
  381. function GetTypeName:string;override;
  382. function is_publishable : boolean;override;
  383. function is_methodpointer:boolean;override;
  384. function is_addressonly:boolean;override;
  385. function getmangledparaname:string;override;
  386. end;
  387. tmessageinf = record
  388. case integer of
  389. 0 : (str : pshortstring);
  390. 1 : (i : longint);
  391. end;
  392. tinlininginfo = record
  393. { node tree }
  394. code : tnode;
  395. flags : tprocinfoflags;
  396. end;
  397. pinlininginfo = ^tinlininginfo;
  398. {$ifdef oldregvars}
  399. { register variables }
  400. pregvarinfo = ^tregvarinfo;
  401. tregvarinfo = record
  402. regvars : array[1..maxvarregs] of tsym;
  403. regvars_para : array[1..maxvarregs] of boolean;
  404. regvars_refs : array[1..maxvarregs] of longint;
  405. fpuregvars : array[1..maxfpuvarregs] of tsym;
  406. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  407. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  408. end;
  409. {$endif oldregvars}
  410. tprocdef = class(tabstractprocdef)
  411. private
  412. _mangledname : pshortstring;
  413. public
  414. messageinf : tmessageinf;
  415. dispid : longint;
  416. extnumber : word;
  417. {$ifndef EXTDEBUG}
  418. { where is this function defined and what were the symbol
  419. flags, needed here because there
  420. is only one symbol for all overloaded functions
  421. EXTDEBUG has fileinfo in tdef (PFV) }
  422. fileinfo : tfileposinfo;
  423. {$endif}
  424. visibility : tvisibility;
  425. symoptions : tsymoptions;
  426. { symbol owning this definition }
  427. procsym : tsym;
  428. procsymderef : tderef;
  429. { alias names }
  430. aliasnames : TCmdStrList;
  431. { symtables }
  432. localst : TSymtable;
  433. funcretsym : tsym;
  434. funcretsymderef : tderef;
  435. _class : tobjectdef;
  436. _classderef : tderef;
  437. {$if defined(powerpc) or defined(m68k)}
  438. { library symbol for AmigaOS/MorphOS }
  439. libsym : tsym;
  440. libsymderef : tderef;
  441. {$endif powerpc or m68k}
  442. { name of the result variable to insert in the localsymtable }
  443. resultname : pshortstring;
  444. { true, if the procedure is only declared
  445. (forward procedure) }
  446. forwarddef,
  447. { true if the procedure is declared in the interface }
  448. interfacedef : boolean;
  449. { true if the procedure has a forward declaration }
  450. hasforward : boolean;
  451. { import info }
  452. import_dll,
  453. import_name : pshortstring;
  454. import_nr : word;
  455. { info for inlining the subroutine, if this pointer is nil,
  456. the procedure can't be inlined }
  457. inlininginfo : pinlininginfo;
  458. {$ifdef oldregvars}
  459. regvarinfo: pregvarinfo;
  460. {$endif oldregvars}
  461. {$ifdef i386}
  462. fpu_used : byte;
  463. {$endif i386}
  464. { position in aasmoutput list }
  465. procstarttai,
  466. procendtai : tai;
  467. constructor create(level:byte);
  468. constructor ppuload(ppufile:tcompilerppufile);
  469. destructor destroy;override;
  470. procedure ppuwrite(ppufile:tcompilerppufile);override;
  471. procedure buildderef;override;
  472. procedure buildderefimpl;override;
  473. procedure deref;override;
  474. procedure derefimpl;override;
  475. procedure reset;override;
  476. function GetSymtable(t:tGetSymtable):TSymtable;override;
  477. function GetTypeName : string;override;
  478. function mangledname : string;
  479. procedure setmangledname(const s : string);
  480. function fullprocname(showhidden:boolean):string;
  481. function cplusplusmangledname : string;
  482. function objcmangledname : string;
  483. function is_methodpointer:boolean;override;
  484. function is_addressonly:boolean;override;
  485. end;
  486. { single linked list of overloaded procs }
  487. pprocdeflist = ^tprocdeflist;
  488. tprocdeflist = record
  489. def : tprocdef;
  490. defderef : tderef;
  491. next : pprocdeflist;
  492. end;
  493. tstringdef = class(tstoreddef)
  494. stringtype : tstringtype;
  495. len : aint;
  496. constructor createshort(l : byte);
  497. constructor loadshort(ppufile:tcompilerppufile);
  498. constructor createlong(l : aint);
  499. constructor loadlong(ppufile:tcompilerppufile);
  500. constructor createansi;
  501. constructor loadansi(ppufile:tcompilerppufile);
  502. constructor createwide;
  503. constructor loadwide(ppufile:tcompilerppufile);
  504. constructor createunicode;
  505. constructor loadunicode(ppufile:tcompilerppufile);
  506. function getcopy : tstoreddef;override;
  507. function stringtypname:string;
  508. procedure ppuwrite(ppufile:tcompilerppufile);override;
  509. function GetTypeName:string;override;
  510. function getmangledparaname:string;override;
  511. function is_publishable : boolean;override;
  512. function alignment : shortint;override;
  513. function needs_inittable : boolean;override;
  514. function getvardef:longint;override;
  515. end;
  516. tenumdef = class(tstoreddef)
  517. minval,
  518. maxval : aint;
  519. has_jumps : boolean;
  520. firstenum : tsym; {tenumsym}
  521. basedef : tenumdef;
  522. basedefderef : tderef;
  523. constructor create;
  524. constructor create_subrange(_basedef:tenumdef;_min,_max:aint);
  525. constructor ppuload(ppufile:tcompilerppufile);
  526. function getcopy : tstoreddef;override;
  527. procedure ppuwrite(ppufile:tcompilerppufile);override;
  528. procedure buildderef;override;
  529. procedure deref;override;
  530. procedure derefimpl;override;
  531. function GetTypeName:string;override;
  532. function is_publishable : boolean;override;
  533. procedure calcsavesize;
  534. function packedbitsize: aint; override;
  535. procedure setmax(_max:aint);
  536. procedure setmin(_min:aint);
  537. function min:aint;
  538. function max:aint;
  539. end;
  540. tsetdef = class(tstoreddef)
  541. elementdef : tdef;
  542. elementdefderef : tderef;
  543. setbase,
  544. setmax : aword;
  545. constructor create(def:tdef;low, high : aint);
  546. constructor ppuload(ppufile:tcompilerppufile);
  547. function getcopy : tstoreddef;override;
  548. procedure ppuwrite(ppufile:tcompilerppufile);override;
  549. procedure buildderef;override;
  550. procedure deref;override;
  551. function GetTypeName:string;override;
  552. function is_publishable : boolean;override;
  553. end;
  554. var
  555. current_objectdef : tobjectdef; { used for private functions check !! }
  556. { default types }
  557. generrordef, { error in definition }
  558. voidpointertype, { pointer for Void-pointeddef }
  559. charpointertype, { pointer for Char-pointeddef }
  560. widecharpointertype, { pointer for WideChar-pointeddef }
  561. voidfarpointertype,
  562. cundefinedtype,
  563. cformaltype, { unique formal definition }
  564. ctypedformaltype, { unique typed formal definition }
  565. voidtype, { Void (procedure) }
  566. cchartype, { Char }
  567. cwidechartype, { WideChar }
  568. booltype, { boolean type }
  569. bool8type,
  570. bool16type,
  571. bool32type,
  572. bool64type, { implement me }
  573. u8inttype, { 8-Bit unsigned integer }
  574. s8inttype, { 8-Bit signed integer }
  575. u16inttype, { 16-Bit unsigned integer }
  576. s16inttype, { 16-Bit signed integer }
  577. u32inttype, { 32-Bit unsigned integer }
  578. s32inttype, { 32-Bit signed integer }
  579. u64inttype, { 64-bit unsigned integer }
  580. s64inttype, { 64-bit signed integer }
  581. s32floattype, { pointer for realconstn }
  582. s64floattype, { pointer for realconstn }
  583. s80floattype, { pointer to type of temp. floats }
  584. s64currencytype, { pointer to a currency type }
  585. cshortstringtype, { pointer to type of short string const }
  586. clongstringtype, { pointer to type of long string const }
  587. cansistringtype, { pointer to type of ansi string const }
  588. cwidestringtype, { pointer to type of wide string const }
  589. cunicodestringtype,
  590. openshortstringtype, { pointer to type of an open shortstring,
  591. needed for readln() }
  592. openchararraytype, { pointer to type of an open array of char,
  593. needed for readln() }
  594. cfiletype, { get the same definition for all file }
  595. { used for stabs }
  596. methodpointertype, { typecasting of methodpointers to extract self }
  597. hresultdef,
  598. { we use only one variant def for every variant class }
  599. cvarianttype,
  600. colevarianttype,
  601. { default integer type s32inttype on 32 bit systems, s64bittype on 64 bit systems }
  602. sinttype,
  603. uinttype,
  604. { unsigned and signed ord type with the same size as a pointer }
  605. ptruinttype,
  606. ptrsinttype,
  607. { several types to simulate more or less C++ objects for GDB }
  608. vmttype,
  609. vmtarraytype,
  610. pvmttype : tdef; { type of classrefs, used for stabs }
  611. { pointer to the anchestor of all classes }
  612. class_tobject : tobjectdef;
  613. { pointer to the ancestor of all COM interfaces }
  614. interface_iunknown : tobjectdef;
  615. { pointer to the TGUID type
  616. of all interfaces }
  617. rec_tguid : trecorddef;
  618. { Objective-C base types }
  619. objc_metaclasstype,
  620. objc_superclasstype,
  621. objc_idtype,
  622. objc_seltype : tpointerdef;
  623. const
  624. {$ifdef i386}
  625. pbestrealtype : ^tdef = @s80floattype;
  626. {$endif}
  627. {$ifdef x86_64}
  628. pbestrealtype : ^tdef = @s80floattype;
  629. {$endif}
  630. {$ifdef m68k}
  631. pbestrealtype : ^tdef = @s64floattype;
  632. {$endif}
  633. {$ifdef alpha}
  634. pbestrealtype : ^tdef = @s64floattype;
  635. {$endif}
  636. {$ifdef powerpc}
  637. pbestrealtype : ^tdef = @s64floattype;
  638. {$endif}
  639. {$ifdef POWERPC64}
  640. pbestrealtype : ^tdef = @s64floattype;
  641. {$endif}
  642. {$ifdef ia64}
  643. pbestrealtype : ^tdef = @s64floattype;
  644. {$endif}
  645. {$ifdef SPARC}
  646. pbestrealtype : ^tdef = @s64floattype;
  647. {$endif SPARC}
  648. {$ifdef vis}
  649. pbestrealtype : ^tdef = @s64floattype;
  650. {$endif vis}
  651. {$ifdef ARM}
  652. pbestrealtype : ^tdef = @s64floattype;
  653. {$endif ARM}
  654. {$ifdef MIPS}
  655. pbestrealtype : ^tdef = @s64floattype;
  656. {$endif MIPS}
  657. {$ifdef AVR}
  658. pbestrealtype : ^tdef = @s64floattype;
  659. {$endif AVR}
  660. function make_mangledname(const typeprefix:string;st:TSymtable;const suffix:string):string;
  661. { should be in the types unit, but the types unit uses the node stuff :( }
  662. function is_interfacecom(def: tdef): boolean;
  663. function is_interfacecorba(def: tdef): boolean;
  664. function is_interface(def: tdef): boolean;
  665. function is_dispinterface(def: tdef): boolean;
  666. function is_object(def: tdef): boolean;
  667. function is_class(def: tdef): boolean;
  668. function is_cppclass(def: tdef): boolean;
  669. function is_objcclass(def: tdef): boolean;
  670. function is_objcclassref(def: tdef): boolean;
  671. function is_class_or_interface(def: tdef): boolean;
  672. function is_class_or_interface_or_object(def: tdef): boolean;
  673. function is_class_or_interface_or_dispinterface(def: tdef): boolean;
  674. procedure loadobjctypes;
  675. {$ifdef x86}
  676. function use_sse(def : tdef) : boolean;
  677. {$endif x86}
  678. implementation
  679. uses
  680. SysUtils,
  681. cutils,
  682. { global }
  683. verbose,
  684. { target }
  685. systems,aasmcpu,paramgr,
  686. { symtable }
  687. symsym,symtable,symutil,defutil,
  688. { module }
  689. fmodule,
  690. { other }
  691. gendef,
  692. fpccrc
  693. ;
  694. {****************************************************************************
  695. Constants
  696. ****************************************************************************}
  697. const
  698. varempty = 0;
  699. varnull = 1;
  700. varsmallint = 2;
  701. varinteger = 3;
  702. varsingle = 4;
  703. vardouble = 5;
  704. varcurrency = 6;
  705. vardate = 7;
  706. varolestr = 8;
  707. vardispatch = 9;
  708. varerror = 10;
  709. varboolean = 11;
  710. varvariant = 12;
  711. varunknown = 13;
  712. vardecimal = 14;
  713. varshortint = 16;
  714. varbyte = 17;
  715. varword = 18;
  716. varlongword = 19;
  717. varint64 = 20;
  718. varqword = 21;
  719. varunicodestr = 22;
  720. varUndefined = -1;
  721. varstrarg = $48;
  722. varstring = $100;
  723. varany = $101;
  724. vardefmask = $fff;
  725. vararray = $2000;
  726. varbyref = $4000;
  727. {****************************************************************************
  728. Helpers
  729. ****************************************************************************}
  730. function make_mangledname(const typeprefix:string;st:TSymtable;const suffix:string):string;
  731. var
  732. s,hs,
  733. prefix : string;
  734. oldlen,
  735. newlen,
  736. i : longint;
  737. crc : dword;
  738. hp : tparavarsym;
  739. begin
  740. prefix:='';
  741. if not assigned(st) then
  742. internalerror(200204212);
  743. { sub procedures }
  744. while (st.symtabletype=localsymtable) do
  745. begin
  746. if st.defowner.typ<>procdef then
  747. internalerror(200204173);
  748. { Add the full mangledname of procedure to prevent
  749. conflicts with 2 overloads having both a nested procedure
  750. with the same name, see tb0314 (PFV) }
  751. s:=tprocdef(st.defowner).procsym.name;
  752. oldlen:=length(s);
  753. for i:=0 to tprocdef(st.defowner).paras.count-1 do
  754. begin
  755. hp:=tparavarsym(tprocdef(st.defowner).paras[i]);
  756. if not(vo_is_hidden_para in hp.varoptions) then
  757. s:=s+'$'+hp.vardef.mangledparaname;
  758. end;
  759. if not is_void(tprocdef(st.defowner).returndef) then
  760. s:=s+'$$'+tprocdef(st.defowner).returndef.mangledparaname;
  761. newlen:=length(s);
  762. { Replace with CRC if the parameter line is very long }
  763. if (newlen-oldlen>12) and
  764. ((newlen+length(prefix)>128) or (newlen-oldlen>32)) then
  765. begin
  766. crc:=0;
  767. for i:=0 to tprocdef(st.defowner).paras.count-1 do
  768. begin
  769. hp:=tparavarsym(tprocdef(st.defowner).paras[i]);
  770. if not(vo_is_hidden_para in hp.varoptions) then
  771. begin
  772. hs:=hp.vardef.mangledparaname;
  773. crc:=UpdateCrc32(crc,hs[1],length(hs));
  774. end;
  775. end;
  776. hs:=hp.vardef.mangledparaname;
  777. crc:=UpdateCrc32(crc,hs[1],length(hs));
  778. s:=Copy(s,1,oldlen)+'$crc'+hexstr(crc,8);
  779. end;
  780. if prefix<>'' then
  781. prefix:=s+'_'+prefix
  782. else
  783. prefix:=s;
  784. st:=st.defowner.owner;
  785. end;
  786. { object/classes symtable }
  787. if (st.symtabletype=ObjectSymtable) then
  788. begin
  789. if st.defowner.typ<>objectdef then
  790. internalerror(200204174);
  791. prefix:=tobjectdef(st.defowner).objname^+'_$_'+prefix;
  792. st:=st.defowner.owner;
  793. end;
  794. { symtable must now be static or global }
  795. if not(st.symtabletype in [staticsymtable,globalsymtable]) then
  796. internalerror(200204175);
  797. result:='';
  798. if typeprefix<>'' then
  799. result:=result+typeprefix+'_';
  800. { Add P$ for program, which can have the same name as
  801. a unit }
  802. if (TSymtable(main_module.localsymtable)=st) and
  803. (not main_module.is_unit) then
  804. result:=result+'P$'+st.name^
  805. else
  806. result:=result+st.name^;
  807. if prefix<>'' then
  808. result:=result+'_'+prefix;
  809. if suffix<>'' then
  810. result:=result+'_'+suffix;
  811. { the Darwin assembler assumes that all symbols starting with 'L' are local }
  812. { Further, the Mac OS X 10.5 linker does not consider symbols which do not }
  813. { start with '_' as regular symbols (it does not generate N_GSYM entries }
  814. { those in the debug map, leading to troubles with dsymutil). So always }
  815. { add an underscore on darwin. }
  816. if (target_info.system in systems_darwin) then
  817. result := '_' + result;
  818. end;
  819. {****************************************************************************
  820. TDEF (base class for definitions)
  821. ****************************************************************************}
  822. constructor tstoreddef.create(dt:tdeftyp);
  823. var
  824. insertstack : psymtablestackitem;
  825. begin
  826. inherited create(dt);
  827. savesize := 0;
  828. {$ifdef EXTDEBUG}
  829. fileinfo := current_filepos;
  830. {$endif}
  831. generictokenbuf:=nil;
  832. genericdef:=nil;
  833. { Don't register forwarddefs, they are disposed at the
  834. end of an type block }
  835. if (dt=forwarddef) then
  836. exit;
  837. { Register in current_module }
  838. if assigned(current_module) then
  839. begin
  840. current_module.deflist.Add(self);
  841. DefId:=current_module.deflist.Count-1;
  842. end;
  843. { Register in symtable stack }
  844. if assigned(symtablestack) then
  845. begin
  846. insertstack:=symtablestack.stack;
  847. while assigned(insertstack) and
  848. (insertstack^.symtable.symtabletype=withsymtable) do
  849. insertstack:=insertstack^.next;
  850. if not assigned(insertstack) then
  851. internalerror(200602044);
  852. insertstack^.symtable.insertdef(self);
  853. end;
  854. end;
  855. destructor tstoreddef.destroy;
  856. begin
  857. { Direct calls are not allowed, use symtable.deletedef() }
  858. if assigned(owner) then
  859. internalerror(200612311);
  860. if assigned(generictokenbuf) then
  861. begin
  862. generictokenbuf.free;
  863. generictokenbuf:=nil;
  864. end;
  865. inherited destroy;
  866. end;
  867. constructor tstoreddef.ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  868. var
  869. sizeleft,i : longint;
  870. buf : array[0..255] of byte;
  871. begin
  872. inherited create(dt);
  873. DefId:=ppufile.getlongint;
  874. current_module.deflist[DefId]:=self;
  875. {$ifdef EXTDEBUG}
  876. fillchar(fileinfo,sizeof(fileinfo),0);
  877. {$endif}
  878. { load }
  879. ppufile.getderef(typesymderef);
  880. ppufile.getsmallset(defoptions);
  881. ppufile.getsmallset(defstates);
  882. if df_generic in defoptions then
  883. begin
  884. sizeleft:=ppufile.getlongint;
  885. initgeneric;
  886. while sizeleft>0 do
  887. begin
  888. if sizeleft>sizeof(buf) then
  889. i:=sizeof(buf)
  890. else
  891. i:=sizeleft;
  892. ppufile.getdata(buf,i);
  893. generictokenbuf.write(buf,i);
  894. dec(sizeleft,i);
  895. end;
  896. end;
  897. if df_specialization in defoptions then
  898. ppufile.getderef(genericdefderef);
  899. end;
  900. function Tstoreddef.rtti_mangledname(rt:trttitype):string;
  901. var
  902. prefix : string[4];
  903. begin
  904. if rt=fullrtti then
  905. begin
  906. prefix:='RTTI';
  907. include(defstates,ds_rtti_table_used);
  908. end
  909. else
  910. begin
  911. prefix:='INIT';
  912. include(defstates,ds_init_table_used);
  913. end;
  914. if assigned(typesym) and
  915. (owner.symtabletype in [staticsymtable,globalsymtable]) then
  916. result:=make_mangledname(prefix,owner,typesym.name)
  917. else
  918. result:=make_mangledname(prefix,findunitsymtable(owner),'DEF'+tostr(DefId))
  919. end;
  920. procedure Tstoreddef.reset;
  921. begin
  922. end;
  923. function tstoreddef.getcopy : tstoreddef;
  924. begin
  925. Message(sym_e_cant_create_unique_type);
  926. getcopy:=terrordef.create;
  927. end;
  928. procedure tstoreddef.ppuwrite(ppufile:tcompilerppufile);
  929. var
  930. sizeleft,i : longint;
  931. buf : array[0..255] of byte;
  932. oldintfcrc : boolean;
  933. begin
  934. ppufile.putlongint(DefId);
  935. ppufile.putderef(typesymderef);
  936. ppufile.putsmallset(defoptions);
  937. oldintfcrc:=ppufile.do_crc;
  938. ppufile.do_crc:=false;
  939. ppufile.putsmallset(defstates);
  940. if df_generic in defoptions then
  941. begin
  942. if assigned(generictokenbuf) then
  943. begin
  944. sizeleft:=generictokenbuf.size;
  945. generictokenbuf.seek(0);
  946. end
  947. else
  948. sizeleft:=0;
  949. ppufile.putlongint(sizeleft);
  950. while sizeleft>0 do
  951. begin
  952. if sizeleft>sizeof(buf) then
  953. i:=sizeof(buf)
  954. else
  955. i:=sizeleft;
  956. generictokenbuf.read(buf,i);
  957. ppufile.putdata(buf,i);
  958. dec(sizeleft,i);
  959. end;
  960. end;
  961. ppufile.do_crc:=oldintfcrc;
  962. if df_specialization in defoptions then
  963. ppufile.putderef(genericdefderef);
  964. end;
  965. procedure tstoreddef.buildderef;
  966. begin
  967. typesymderef.build(typesym);
  968. genericdefderef.build(genericdef);
  969. end;
  970. procedure tstoreddef.buildderefimpl;
  971. begin
  972. end;
  973. procedure tstoreddef.deref;
  974. begin
  975. typesym:=ttypesym(typesymderef.resolve);
  976. if df_specialization in defoptions then
  977. genericdef:=tstoreddef(genericdefderef.resolve);
  978. end;
  979. procedure tstoreddef.derefimpl;
  980. begin
  981. end;
  982. function tstoreddef.size : aint;
  983. begin
  984. size:=savesize;
  985. end;
  986. function tstoreddef.getvardef:longint;
  987. begin
  988. result:=varUndefined;
  989. end;
  990. function tstoreddef.alignment : shortint;
  991. begin
  992. { natural alignment by default }
  993. alignment:=size_2_align(savesize);
  994. { can happen if savesize = 0, e.g. for voiddef or
  995. an empty record
  996. }
  997. if (alignment=0) then
  998. alignment:=1;
  999. end;
  1000. { returns true, if the definition can be published }
  1001. function tstoreddef.is_publishable : boolean;
  1002. begin
  1003. is_publishable:=false;
  1004. end;
  1005. { needs an init table }
  1006. function tstoreddef.needs_inittable : boolean;
  1007. begin
  1008. needs_inittable:=false;
  1009. end;
  1010. function tstoreddef.is_intregable : boolean;
  1011. var
  1012. recsize,temp: longint;
  1013. begin
  1014. is_intregable:=false;
  1015. case typ of
  1016. orddef,
  1017. pointerdef,
  1018. enumdef,
  1019. classrefdef:
  1020. is_intregable:=true;
  1021. procvardef :
  1022. is_intregable:=not(po_methodpointer in tprocvardef(self).procoptions);
  1023. objectdef:
  1024. is_intregable:=(is_class(self) or is_interface(self)) and not needs_inittable;
  1025. setdef:
  1026. is_intregable:=is_smallset(self);
  1027. recorddef:
  1028. begin
  1029. recsize:=size;
  1030. is_intregable:=
  1031. ispowerof2(recsize,temp) and
  1032. (recsize <= sizeof(aint));
  1033. end;
  1034. end;
  1035. end;
  1036. function tstoreddef.is_fpuregable : boolean;
  1037. begin
  1038. {$ifdef x86}
  1039. result:=use_sse(self);
  1040. {$else x86}
  1041. result:=(typ=floatdef) and not(cs_fp_emulation in current_settings.moduleswitches);
  1042. {$endif x86}
  1043. end;
  1044. procedure tstoreddef.initgeneric;
  1045. begin
  1046. if assigned(generictokenbuf) then
  1047. internalerror(200512131);
  1048. generictokenbuf:=tdynamicarray.create(256);
  1049. end;
  1050. {****************************************************************************
  1051. Tstringdef
  1052. ****************************************************************************}
  1053. constructor tstringdef.createshort(l : byte);
  1054. begin
  1055. inherited create(stringdef);
  1056. stringtype:=st_shortstring;
  1057. len:=l;
  1058. savesize:=len+1;
  1059. end;
  1060. constructor tstringdef.loadshort(ppufile:tcompilerppufile);
  1061. begin
  1062. inherited ppuload(stringdef,ppufile);
  1063. stringtype:=st_shortstring;
  1064. len:=ppufile.getbyte;
  1065. savesize:=len+1;
  1066. end;
  1067. constructor tstringdef.createlong(l : aint);
  1068. begin
  1069. inherited create(stringdef);
  1070. stringtype:=st_longstring;
  1071. len:=l;
  1072. savesize:=sizeof(pint);
  1073. end;
  1074. constructor tstringdef.loadlong(ppufile:tcompilerppufile);
  1075. begin
  1076. inherited ppuload(stringdef,ppufile);
  1077. stringtype:=st_longstring;
  1078. len:=ppufile.getaint;
  1079. savesize:=sizeof(pint);
  1080. end;
  1081. constructor tstringdef.createansi;
  1082. begin
  1083. inherited create(stringdef);
  1084. stringtype:=st_ansistring;
  1085. len:=-1;
  1086. savesize:=sizeof(pint);
  1087. end;
  1088. constructor tstringdef.loadansi(ppufile:tcompilerppufile);
  1089. begin
  1090. inherited ppuload(stringdef,ppufile);
  1091. stringtype:=st_ansistring;
  1092. len:=ppufile.getaint;
  1093. savesize:=sizeof(pint);
  1094. end;
  1095. constructor tstringdef.createwide;
  1096. begin
  1097. inherited create(stringdef);
  1098. stringtype:=st_widestring;
  1099. len:=-1;
  1100. savesize:=sizeof(pint);
  1101. end;
  1102. constructor tstringdef.loadwide(ppufile:tcompilerppufile);
  1103. begin
  1104. inherited ppuload(stringdef,ppufile);
  1105. stringtype:=st_widestring;
  1106. len:=ppufile.getaint;
  1107. savesize:=sizeof(pint);
  1108. end;
  1109. constructor tstringdef.createunicode;
  1110. begin
  1111. inherited create(stringdef);
  1112. stringtype:=st_unicodestring;
  1113. len:=-1;
  1114. savesize:=sizeof(pint);
  1115. end;
  1116. constructor tstringdef.loadunicode(ppufile:tcompilerppufile);
  1117. begin
  1118. inherited ppuload(stringdef,ppufile);
  1119. stringtype:=st_unicodestring;
  1120. len:=ppufile.getaint;
  1121. savesize:=sizeof(pint);
  1122. end;
  1123. function tstringdef.getcopy : tstoreddef;
  1124. begin
  1125. result:=tstringdef.create(typ);
  1126. result.typ:=stringdef;
  1127. tstringdef(result).stringtype:=stringtype;
  1128. tstringdef(result).len:=len;
  1129. tstringdef(result).savesize:=savesize;
  1130. end;
  1131. function tstringdef.stringtypname:string;
  1132. const
  1133. typname:array[tstringtype] of string[10]=(
  1134. 'shortstr','longstr','ansistr','widestr','unicodestr'
  1135. );
  1136. begin
  1137. stringtypname:=typname[stringtype];
  1138. end;
  1139. procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
  1140. begin
  1141. inherited ppuwrite(ppufile);
  1142. if stringtype=st_shortstring then
  1143. begin
  1144. {$ifdef extdebug}
  1145. if len > 255 then internalerror(12122002);
  1146. {$endif}
  1147. ppufile.putbyte(byte(len))
  1148. end
  1149. else
  1150. ppufile.putaint(len);
  1151. case stringtype of
  1152. st_shortstring : ppufile.writeentry(ibshortstringdef);
  1153. st_longstring : ppufile.writeentry(iblongstringdef);
  1154. st_ansistring : ppufile.writeentry(ibansistringdef);
  1155. st_widestring : ppufile.writeentry(ibwidestringdef);
  1156. st_unicodestring : ppufile.writeentry(ibunicodestringdef);
  1157. end;
  1158. end;
  1159. function tstringdef.needs_inittable : boolean;
  1160. begin
  1161. needs_inittable:=stringtype in [st_ansistring,st_widestring,st_unicodestring];
  1162. end;
  1163. function tstringdef.GetTypeName : string;
  1164. const
  1165. names : array[tstringtype] of string[15] = (
  1166. 'ShortString','LongString','AnsiString','WideString','UnicodeString');
  1167. begin
  1168. GetTypeName:=names[stringtype];
  1169. end;
  1170. function tstringdef.getvardef : longint;
  1171. const
  1172. vardef : array[tstringtype] of longint = (
  1173. varUndefined,varUndefined,varString,varOleStr,varUnicodeStr);
  1174. begin
  1175. result:=vardef[stringtype];
  1176. end;
  1177. function tstringdef.alignment : shortint;
  1178. begin
  1179. case stringtype of
  1180. st_unicodestring,
  1181. st_widestring,
  1182. st_ansistring:
  1183. alignment:=size_2_align(savesize);
  1184. st_longstring,
  1185. st_shortstring:
  1186. { char to string accesses byte 0 and 1 with one word access }
  1187. if (tf_requires_proper_alignment in target_info.flags) or
  1188. { macpas needs an alignment of 2 (MetroWerks compatible) }
  1189. (m_mac in current_settings.modeswitches) then
  1190. alignment:=size_2_align(2)
  1191. else
  1192. alignment:=size_2_align(1);
  1193. else
  1194. internalerror(200412301);
  1195. end;
  1196. end;
  1197. function tstringdef.getmangledparaname : string;
  1198. begin
  1199. getmangledparaname:='STRING';
  1200. end;
  1201. function tstringdef.is_publishable : boolean;
  1202. begin
  1203. is_publishable:=true;
  1204. end;
  1205. {****************************************************************************
  1206. TENUMDEF
  1207. ****************************************************************************}
  1208. constructor tenumdef.create;
  1209. begin
  1210. inherited create(enumdef);
  1211. minval:=0;
  1212. maxval:=0;
  1213. calcsavesize;
  1214. has_jumps:=false;
  1215. basedef:=nil;
  1216. firstenum:=nil;
  1217. end;
  1218. constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:aint);
  1219. begin
  1220. inherited create(enumdef);
  1221. minval:=_min;
  1222. maxval:=_max;
  1223. basedef:=_basedef;
  1224. calcsavesize;
  1225. has_jumps:=false;
  1226. firstenum:=basedef.firstenum;
  1227. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1228. firstenum:=tenumsym(firstenum).nextenum;
  1229. end;
  1230. constructor tenumdef.ppuload(ppufile:tcompilerppufile);
  1231. begin
  1232. inherited ppuload(enumdef,ppufile);
  1233. ppufile.getderef(basedefderef);
  1234. minval:=ppufile.getaint;
  1235. maxval:=ppufile.getaint;
  1236. savesize:=ppufile.getaint;
  1237. has_jumps:=false;
  1238. firstenum:=Nil;
  1239. end;
  1240. function tenumdef.getcopy : tstoreddef;
  1241. begin
  1242. if assigned(basedef) then
  1243. result:=tenumdef.create_subrange(basedef,minval,maxval)
  1244. else
  1245. begin
  1246. result:=tenumdef.create;
  1247. tenumdef(result).minval:=minval;
  1248. tenumdef(result).maxval:=maxval;
  1249. end;
  1250. tenumdef(result).has_jumps:=has_jumps;
  1251. tenumdef(result).firstenum:=firstenum;
  1252. tenumdef(result).basedefderef:=basedefderef;
  1253. end;
  1254. procedure tenumdef.calcsavesize;
  1255. begin
  1256. if (current_settings.packenum=8) or (min<low(longint)) or (int64(max)>high(cardinal)) then
  1257. savesize:=8
  1258. else
  1259. if (current_settings.packenum=4) or (min<low(smallint)) or (max>high(word)) then
  1260. savesize:=4
  1261. else
  1262. if (current_settings.packenum=2) or (min<low(shortint)) or (max>high(byte)) then
  1263. savesize:=2
  1264. else
  1265. savesize:=1;
  1266. end;
  1267. function tenumdef.packedbitsize: aint;
  1268. var
  1269. sizeval: tconstexprint;
  1270. power: longint;
  1271. begin
  1272. result := 0;
  1273. if (minval >= 0) and
  1274. (maxval <= 1) then
  1275. result := 1
  1276. else
  1277. begin
  1278. if (minval>=0) then
  1279. sizeval:=maxval
  1280. else
  1281. { don't count 0 twice }
  1282. sizeval:=(cutils.max(-minval,maxval)*2)-1;
  1283. { 256 must become 512 etc. }
  1284. nextpowerof2(sizeval+1,power);
  1285. result := power;
  1286. end;
  1287. end;
  1288. procedure tenumdef.setmax(_max:aint);
  1289. begin
  1290. maxval:=_max;
  1291. calcsavesize;
  1292. end;
  1293. procedure tenumdef.setmin(_min:aint);
  1294. begin
  1295. minval:=_min;
  1296. calcsavesize;
  1297. end;
  1298. function tenumdef.min:aint;
  1299. begin
  1300. min:=minval;
  1301. end;
  1302. function tenumdef.max:aint;
  1303. begin
  1304. max:=maxval;
  1305. end;
  1306. procedure tenumdef.buildderef;
  1307. begin
  1308. inherited buildderef;
  1309. basedefderef.build(basedef);
  1310. end;
  1311. procedure tenumdef.deref;
  1312. begin
  1313. inherited deref;
  1314. basedef:=tenumdef(basedefderef.resolve);
  1315. { restart ordering }
  1316. firstenum:=nil;
  1317. end;
  1318. procedure tenumdef.derefimpl;
  1319. begin
  1320. if assigned(basedef) and
  1321. (firstenum=nil) then
  1322. begin
  1323. firstenum:=basedef.firstenum;
  1324. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1325. firstenum:=tenumsym(firstenum).nextenum;
  1326. end;
  1327. end;
  1328. procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
  1329. begin
  1330. inherited ppuwrite(ppufile);
  1331. ppufile.putderef(basedefderef);
  1332. ppufile.putaint(min);
  1333. ppufile.putaint(max);
  1334. ppufile.putaint(savesize);
  1335. ppufile.writeentry(ibenumdef);
  1336. end;
  1337. function tenumdef.is_publishable : boolean;
  1338. begin
  1339. is_publishable:=true;
  1340. end;
  1341. function tenumdef.GetTypeName : string;
  1342. begin
  1343. GetTypeName:='<enumeration type>';
  1344. end;
  1345. {****************************************************************************
  1346. TORDDEF
  1347. ****************************************************************************}
  1348. constructor torddef.create(t : tordtype;v,b : TConstExprInt);
  1349. begin
  1350. inherited create(orddef);
  1351. low:=v;
  1352. high:=b;
  1353. ordtype:=t;
  1354. setsize;
  1355. end;
  1356. constructor torddef.ppuload(ppufile:tcompilerppufile);
  1357. begin
  1358. inherited ppuload(orddef,ppufile);
  1359. ordtype:=tordtype(ppufile.getbyte);
  1360. low:=ppufile.getexprint;
  1361. high:=ppufile.getexprint;
  1362. setsize;
  1363. end;
  1364. function torddef.getcopy : tstoreddef;
  1365. begin
  1366. result:=torddef.create(ordtype,low,high);
  1367. result.typ:=orddef;
  1368. torddef(result).low:=low;
  1369. torddef(result).high:=high;
  1370. torddef(result).ordtype:=ordtype;
  1371. torddef(result).savesize:=savesize;
  1372. end;
  1373. function torddef.alignment:shortint;
  1374. begin
  1375. if (target_info.system in [system_i386_darwin,system_arm_darwin]) and
  1376. (ordtype in [s64bit,u64bit]) then
  1377. result := 4
  1378. else
  1379. result := inherited alignment;
  1380. end;
  1381. procedure torddef.setsize;
  1382. const
  1383. sizetbl : array[tordtype] of longint = (
  1384. 0,
  1385. 1,2,4,8,
  1386. 1,2,4,8,
  1387. 1,1,2,4,8,
  1388. 1,2,8
  1389. );
  1390. begin
  1391. savesize:=sizetbl[ordtype];
  1392. end;
  1393. function torddef.packedbitsize: aint;
  1394. var
  1395. sizeval: tconstexprint;
  1396. power: longint;
  1397. begin
  1398. result := 0;
  1399. if ordtype = uvoid then
  1400. exit;
  1401. if (ordtype = u64bit) or
  1402. ((ordtype = s64bit) and
  1403. ((low <= (system.low(int64) div 2)) or
  1404. (high > (system.high(int64) div 2)))) then
  1405. result := 64
  1406. else if (low >= 0) and
  1407. (high <= 1) then
  1408. result := 1
  1409. else
  1410. begin
  1411. if (low>=0) then
  1412. sizeval:=high
  1413. else
  1414. { don't count 0 twice }
  1415. sizeval:=(cutils.max(-low,high)*2)-1;
  1416. { 256 must become 512 etc. }
  1417. nextpowerof2(sizeval+1,power);
  1418. result := power;
  1419. end;
  1420. end;
  1421. function torddef.getvardef : longint;
  1422. const
  1423. basetype2vardef : array[tordtype] of longint = (
  1424. varUndefined,
  1425. varbyte,varqword,varlongword,varqword,
  1426. varshortint,varsmallint,varinteger,varint64,
  1427. varboolean,varboolean,varboolean,varUndefined,varUndefined,
  1428. varUndefined,varUndefined,varCurrency);
  1429. begin
  1430. result:=basetype2vardef[ordtype];
  1431. end;
  1432. procedure torddef.ppuwrite(ppufile:tcompilerppufile);
  1433. begin
  1434. inherited ppuwrite(ppufile);
  1435. ppufile.putbyte(byte(ordtype));
  1436. ppufile.putexprint(low);
  1437. ppufile.putexprint(high);
  1438. ppufile.writeentry(iborddef);
  1439. end;
  1440. function torddef.is_publishable : boolean;
  1441. begin
  1442. is_publishable:=(ordtype<>uvoid);
  1443. end;
  1444. function torddef.GetTypeName : string;
  1445. const
  1446. names : array[tordtype] of string[20] = (
  1447. 'untyped',
  1448. 'Byte','Word','DWord','QWord',
  1449. 'ShortInt','SmallInt','LongInt','Int64',
  1450. 'Boolean','ByteBool','WordBool','LongBool','QWordBool',
  1451. 'Char','WideChar','Currency');
  1452. begin
  1453. GetTypeName:=names[ordtype];
  1454. end;
  1455. {****************************************************************************
  1456. TFLOATDEF
  1457. ****************************************************************************}
  1458. constructor tfloatdef.create(t : tfloattype);
  1459. begin
  1460. inherited create(floatdef);
  1461. floattype:=t;
  1462. setsize;
  1463. end;
  1464. constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
  1465. begin
  1466. inherited ppuload(floatdef,ppufile);
  1467. floattype:=tfloattype(ppufile.getbyte);
  1468. setsize;
  1469. end;
  1470. function tfloatdef.getcopy : tstoreddef;
  1471. begin
  1472. result:=tfloatdef.create(floattype);
  1473. result.typ:=floatdef;
  1474. tfloatdef(result).savesize:=savesize;
  1475. end;
  1476. function tfloatdef.alignment:shortint;
  1477. begin
  1478. if (target_info.system in [system_i386_darwin,system_arm_darwin]) then
  1479. case floattype of
  1480. s80real : result:=16;
  1481. s64real,
  1482. s64currency,
  1483. s64comp : result:=4;
  1484. else
  1485. result := inherited alignment;
  1486. end
  1487. else
  1488. result := inherited alignment;
  1489. end;
  1490. procedure tfloatdef.setsize;
  1491. begin
  1492. case floattype of
  1493. s32real : savesize:=4;
  1494. s80real : savesize:=10;
  1495. s64real,
  1496. s64currency,
  1497. s64comp : savesize:=8;
  1498. else
  1499. savesize:=0;
  1500. end;
  1501. end;
  1502. function tfloatdef.getvardef : longint;
  1503. const
  1504. floattype2vardef : array[tfloattype] of longint = (
  1505. varSingle,varDouble,varUndefined,
  1506. varUndefined,varCurrency,varUndefined);
  1507. begin
  1508. if (upper(typename)='TDATETIME') and
  1509. assigned(owner) and
  1510. assigned(owner.name) and
  1511. (owner.name^='SYSTEM') then
  1512. result:=varDate
  1513. else
  1514. result:=floattype2vardef[floattype];
  1515. end;
  1516. procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
  1517. begin
  1518. inherited ppuwrite(ppufile);
  1519. ppufile.putbyte(byte(floattype));
  1520. ppufile.writeentry(ibfloatdef);
  1521. end;
  1522. function tfloatdef.is_publishable : boolean;
  1523. begin
  1524. is_publishable:=true;
  1525. end;
  1526. function tfloatdef.GetTypeName : string;
  1527. const
  1528. names : array[tfloattype] of string[20] = (
  1529. 'Single','Double','Extended','Comp','Currency','Float128');
  1530. begin
  1531. GetTypeName:=names[floattype];
  1532. end;
  1533. {****************************************************************************
  1534. TFILEDEF
  1535. ****************************************************************************}
  1536. constructor tfiledef.createtext;
  1537. begin
  1538. inherited create(filedef);
  1539. filetyp:=ft_text;
  1540. typedfiledef:=nil;
  1541. setsize;
  1542. end;
  1543. constructor tfiledef.createuntyped;
  1544. begin
  1545. inherited create(filedef);
  1546. filetyp:=ft_untyped;
  1547. typedfiledef:=nil;
  1548. setsize;
  1549. end;
  1550. constructor tfiledef.createtyped(def:tdef);
  1551. begin
  1552. inherited create(filedef);
  1553. filetyp:=ft_typed;
  1554. typedfiledef:=def;
  1555. setsize;
  1556. end;
  1557. constructor tfiledef.ppuload(ppufile:tcompilerppufile);
  1558. begin
  1559. inherited ppuload(filedef,ppufile);
  1560. filetyp:=tfiletyp(ppufile.getbyte);
  1561. if filetyp=ft_typed then
  1562. ppufile.getderef(typedfiledefderef)
  1563. else
  1564. typedfiledef:=nil;
  1565. setsize;
  1566. end;
  1567. function tfiledef.getcopy : tstoreddef;
  1568. begin
  1569. case filetyp of
  1570. ft_typed:
  1571. result:=tfiledef.createtyped(typedfiledef);
  1572. ft_untyped:
  1573. result:=tfiledef.createuntyped;
  1574. ft_text:
  1575. result:=tfiledef.createtext;
  1576. else
  1577. internalerror(2004121201);
  1578. end;
  1579. end;
  1580. procedure tfiledef.buildderef;
  1581. begin
  1582. inherited buildderef;
  1583. if filetyp=ft_typed then
  1584. typedfiledefderef.build(typedfiledef);
  1585. end;
  1586. procedure tfiledef.deref;
  1587. begin
  1588. inherited deref;
  1589. if filetyp=ft_typed then
  1590. typedfiledef:=tdef(typedfiledefderef.resolve);
  1591. end;
  1592. procedure tfiledef.setsize;
  1593. begin
  1594. {$ifdef cpu64bitaddr}
  1595. case filetyp of
  1596. ft_text :
  1597. if target_info.system in [system_x86_64_win64,system_ia64_win64] then
  1598. savesize:=632{+8}
  1599. else
  1600. savesize:=628{+8};
  1601. ft_typed,
  1602. ft_untyped :
  1603. if target_info.system in [system_x86_64_win64,system_ia64_win64] then
  1604. savesize:=372
  1605. else
  1606. savesize:=368;
  1607. end;
  1608. {$else cpu64bitaddr}
  1609. case filetyp of
  1610. ft_text :
  1611. savesize:=592{+4};
  1612. ft_typed,
  1613. ft_untyped :
  1614. savesize:=332;
  1615. end;
  1616. {$endif cpu64bitaddr}
  1617. end;
  1618. procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
  1619. begin
  1620. inherited ppuwrite(ppufile);
  1621. ppufile.putbyte(byte(filetyp));
  1622. if filetyp=ft_typed then
  1623. ppufile.putderef(typedfiledefderef);
  1624. ppufile.writeentry(ibfiledef);
  1625. end;
  1626. function tfiledef.GetTypeName : string;
  1627. begin
  1628. case filetyp of
  1629. ft_untyped:
  1630. GetTypeName:='File';
  1631. ft_typed:
  1632. GetTypeName:='File Of '+typedfiledef.typename;
  1633. ft_text:
  1634. GetTypeName:='Text'
  1635. end;
  1636. end;
  1637. function tfiledef.getmangledparaname : string;
  1638. begin
  1639. case filetyp of
  1640. ft_untyped:
  1641. getmangledparaname:='FILE';
  1642. ft_typed:
  1643. getmangledparaname:='FILE$OF$'+typedfiledef.mangledparaname;
  1644. ft_text:
  1645. getmangledparaname:='TEXT'
  1646. end;
  1647. end;
  1648. {****************************************************************************
  1649. TVARIANTDEF
  1650. ****************************************************************************}
  1651. constructor tvariantdef.create(v : tvarianttype);
  1652. begin
  1653. inherited create(variantdef);
  1654. varianttype:=v;
  1655. setsize;
  1656. end;
  1657. constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
  1658. begin
  1659. inherited ppuload(variantdef,ppufile);
  1660. varianttype:=tvarianttype(ppufile.getbyte);
  1661. setsize;
  1662. end;
  1663. function tvariantdef.getcopy : tstoreddef;
  1664. begin
  1665. result:=tvariantdef.create(varianttype);
  1666. end;
  1667. procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
  1668. begin
  1669. inherited ppuwrite(ppufile);
  1670. ppufile.putbyte(byte(varianttype));
  1671. ppufile.writeentry(ibvariantdef);
  1672. end;
  1673. function tvariantdef.getvardef : longint;
  1674. begin
  1675. Result:=varVariant;
  1676. end;
  1677. procedure tvariantdef.setsize;
  1678. begin
  1679. {$ifdef cpu64bitaddr}
  1680. savesize:=24;
  1681. {$else cpu64bitaddr}
  1682. savesize:=16;
  1683. {$endif cpu64bitaddr}
  1684. end;
  1685. function tvariantdef.GetTypeName : string;
  1686. begin
  1687. case varianttype of
  1688. vt_normalvariant:
  1689. GetTypeName:='Variant';
  1690. vt_olevariant:
  1691. GetTypeName:='OleVariant';
  1692. end;
  1693. end;
  1694. function tvariantdef.needs_inittable : boolean;
  1695. begin
  1696. needs_inittable:=true;
  1697. end;
  1698. function tvariantdef.is_publishable : boolean;
  1699. begin
  1700. is_publishable:=true;
  1701. end;
  1702. {****************************************************************************
  1703. TABSTRACtpointerdef
  1704. ****************************************************************************}
  1705. constructor tabstractpointerdef.create(dt:tdeftyp;def:tdef);
  1706. begin
  1707. inherited create(dt);
  1708. pointeddef:=def;
  1709. savesize:=sizeof(pint);
  1710. end;
  1711. constructor tabstractpointerdef.ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  1712. begin
  1713. inherited ppuload(dt,ppufile);
  1714. ppufile.getderef(pointeddefderef);
  1715. savesize:=sizeof(pint);
  1716. end;
  1717. procedure tabstractpointerdef.buildderef;
  1718. begin
  1719. inherited buildderef;
  1720. pointeddefderef.build(pointeddef);
  1721. end;
  1722. procedure tabstractpointerdef.deref;
  1723. begin
  1724. inherited deref;
  1725. pointeddef:=tdef(pointeddefderef.resolve);
  1726. end;
  1727. procedure tabstractpointerdef.ppuwrite(ppufile:tcompilerppufile);
  1728. begin
  1729. inherited ppuwrite(ppufile);
  1730. ppufile.putderef(pointeddefderef);
  1731. end;
  1732. {****************************************************************************
  1733. tpointerdef
  1734. ****************************************************************************}
  1735. constructor tpointerdef.create(def:tdef);
  1736. begin
  1737. inherited create(pointerdef,def);
  1738. is_far:=false;
  1739. end;
  1740. constructor tpointerdef.createfar(def:tdef);
  1741. begin
  1742. inherited create(pointerdef,def);
  1743. is_far:=true;
  1744. end;
  1745. constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
  1746. begin
  1747. inherited ppuload(pointerdef,ppufile);
  1748. is_far:=(ppufile.getbyte<>0);
  1749. end;
  1750. function tpointerdef.getcopy : tstoreddef;
  1751. begin
  1752. result:=tpointerdef.create(pointeddef);
  1753. tpointerdef(result).is_far:=is_far;
  1754. tpointerdef(result).savesize:=savesize;
  1755. end;
  1756. procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
  1757. begin
  1758. inherited ppuwrite(ppufile);
  1759. ppufile.putbyte(byte(is_far));
  1760. ppufile.writeentry(ibpointerdef);
  1761. end;
  1762. function tpointerdef.GetTypeName : string;
  1763. begin
  1764. if is_far then
  1765. GetTypeName:='^'+pointeddef.typename+';far'
  1766. else
  1767. GetTypeName:='^'+pointeddef.typename;
  1768. end;
  1769. {****************************************************************************
  1770. TCLASSREFDEF
  1771. ****************************************************************************}
  1772. constructor tclassrefdef.create(def:tdef);
  1773. begin
  1774. inherited create(classrefdef,def);
  1775. end;
  1776. constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
  1777. begin
  1778. inherited ppuload(classrefdef,ppufile);
  1779. end;
  1780. procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
  1781. begin
  1782. inherited ppuwrite(ppufile);
  1783. ppufile.writeentry(ibclassrefdef);
  1784. end;
  1785. function tclassrefdef.GetTypeName : string;
  1786. begin
  1787. GetTypeName:='Class Of '+pointeddef.typename;
  1788. end;
  1789. function tclassrefdef.is_publishable : boolean;
  1790. begin
  1791. result:=true;
  1792. end;
  1793. procedure tclassrefdef.reset;
  1794. begin
  1795. tobjectdef(pointeddef).classref_created_in_current_module:=false;
  1796. inherited reset;
  1797. end;
  1798. procedure tclassrefdef.register_created_object_type;
  1799. begin
  1800. tobjectdef(pointeddef).register_created_classref_type;
  1801. end;
  1802. {***************************************************************************
  1803. TSETDEF
  1804. ***************************************************************************}
  1805. constructor tsetdef.create(def:tdef;low, high : aint);
  1806. var
  1807. setallocbits: aint;
  1808. packedsavesize: aint;
  1809. begin
  1810. inherited create(setdef);
  1811. elementdef:=def;
  1812. setmax:=high;
  1813. if (current_settings.setalloc=0) then
  1814. begin
  1815. setbase:=0;
  1816. if (high<32) then
  1817. savesize:=Sizeof(longint)
  1818. else if (high<256) then
  1819. savesize:=32
  1820. else
  1821. savesize:=(high+7) div 8
  1822. end
  1823. else
  1824. begin
  1825. setallocbits:=current_settings.setalloc*8;
  1826. setbase:=low and not(setallocbits-1);
  1827. packedsavesize:=current_settings.setalloc*((((high+setallocbits)-setbase)) DIV setallocbits);
  1828. savesize:=packedsavesize;
  1829. if savesize=3 then
  1830. savesize:=4;
  1831. end;
  1832. end;
  1833. constructor tsetdef.ppuload(ppufile:tcompilerppufile);
  1834. begin
  1835. inherited ppuload(setdef,ppufile);
  1836. ppufile.getderef(elementdefderef);
  1837. savesize:=ppufile.getaint;
  1838. setbase:=ppufile.getaint;
  1839. setmax:=ppufile.getaint;
  1840. end;
  1841. function tsetdef.getcopy : tstoreddef;
  1842. begin
  1843. result:=tsetdef.create(elementdef,setbase,setmax);
  1844. { the copy might have been created with a different setalloc setting }
  1845. tsetdef(result).savesize:=savesize;
  1846. end;
  1847. procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
  1848. begin
  1849. inherited ppuwrite(ppufile);
  1850. ppufile.putderef(elementdefderef);
  1851. ppufile.putaint(savesize);
  1852. ppufile.putaint(setbase);
  1853. ppufile.putaint(setmax);
  1854. ppufile.writeentry(ibsetdef);
  1855. end;
  1856. procedure tsetdef.buildderef;
  1857. begin
  1858. inherited buildderef;
  1859. elementdefderef.build(elementdef);
  1860. end;
  1861. procedure tsetdef.deref;
  1862. begin
  1863. inherited deref;
  1864. elementdef:=tdef(elementdefderef.resolve);
  1865. end;
  1866. function tsetdef.is_publishable : boolean;
  1867. begin
  1868. is_publishable:=savesize in [1,2,4];
  1869. end;
  1870. function tsetdef.GetTypeName : string;
  1871. begin
  1872. if assigned(elementdef) then
  1873. GetTypeName:='Set Of '+elementdef.typename
  1874. else
  1875. GetTypeName:='Empty Set';
  1876. end;
  1877. {***************************************************************************
  1878. TFORMALDEF
  1879. ***************************************************************************}
  1880. constructor tformaldef.create(Atyped:boolean);
  1881. begin
  1882. inherited create(formaldef);
  1883. typed:=Atyped;
  1884. savesize:=0;
  1885. end;
  1886. constructor tformaldef.ppuload(ppufile:tcompilerppufile);
  1887. begin
  1888. inherited ppuload(formaldef,ppufile);
  1889. typed:=boolean(ppufile.getbyte);
  1890. savesize:=0;
  1891. end;
  1892. procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
  1893. begin
  1894. inherited ppuwrite(ppufile);
  1895. ppufile.putbyte(byte(typed));
  1896. ppufile.writeentry(ibformaldef);
  1897. end;
  1898. function tformaldef.GetTypeName : string;
  1899. begin
  1900. if typed then
  1901. GetTypeName:='<Typed formal type>'
  1902. else
  1903. GetTypeName:='<Formal type>';
  1904. end;
  1905. {***************************************************************************
  1906. TARRAYDEF
  1907. ***************************************************************************}
  1908. constructor tarraydef.create(l,h : aint;def:tdef);
  1909. begin
  1910. inherited create(arraydef);
  1911. lowrange:=l;
  1912. highrange:=h;
  1913. rangedef:=def;
  1914. _elementdef:=nil;
  1915. arrayoptions:=[];
  1916. end;
  1917. constructor tarraydef.create_from_pointer(def:tdef);
  1918. begin
  1919. { use -1 so that the elecount will not overflow }
  1920. self.create(0,high(aint)-1,s32inttype);
  1921. arrayoptions:=[ado_IsConvertedPointer];
  1922. setelementdef(def);
  1923. end;
  1924. constructor tarraydef.ppuload(ppufile:tcompilerppufile);
  1925. begin
  1926. inherited ppuload(arraydef,ppufile);
  1927. { the addresses are calculated later }
  1928. ppufile.getderef(_elementdefderef);
  1929. ppufile.getderef(rangedefderef);
  1930. lowrange:=ppufile.getaint;
  1931. highrange:=ppufile.getaint;
  1932. ppufile.getsmallset(arrayoptions);
  1933. end;
  1934. function tarraydef.getcopy : tstoreddef;
  1935. begin
  1936. result:=tarraydef.create(lowrange,highrange,rangedef);
  1937. tarraydef(result).arrayoptions:=arrayoptions;
  1938. tarraydef(result)._elementdef:=_elementdef;
  1939. end;
  1940. procedure tarraydef.buildderef;
  1941. begin
  1942. inherited buildderef;
  1943. _elementdefderef.build(_elementdef);
  1944. rangedefderef.build(rangedef);
  1945. end;
  1946. procedure tarraydef.deref;
  1947. begin
  1948. inherited deref;
  1949. _elementdef:=tdef(_elementdefderef.resolve);
  1950. rangedef:=tdef(rangedefderef.resolve);
  1951. end;
  1952. procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
  1953. begin
  1954. inherited ppuwrite(ppufile);
  1955. ppufile.putderef(_elementdefderef);
  1956. ppufile.putderef(rangedefderef);
  1957. ppufile.putaint(lowrange);
  1958. ppufile.putaint(highrange);
  1959. ppufile.putsmallset(arrayoptions);
  1960. ppufile.writeentry(ibarraydef);
  1961. end;
  1962. function tarraydef.elesize : aint;
  1963. begin
  1964. if (ado_IsBitPacked in arrayoptions) then
  1965. internalerror(2006080101);
  1966. if assigned(_elementdef) then
  1967. result:=_elementdef.size
  1968. else
  1969. result:=0;
  1970. end;
  1971. function tarraydef.elepackedbitsize : aint;
  1972. begin
  1973. if not(ado_IsBitPacked in arrayoptions) then
  1974. internalerror(2006080102);
  1975. if assigned(_elementdef) then
  1976. result:=_elementdef.packedbitsize
  1977. else
  1978. result:=0;
  1979. end;
  1980. function tarraydef.elecount : aword;
  1981. var
  1982. qhigh,qlow : qword;
  1983. begin
  1984. if ado_IsDynamicArray in arrayoptions then
  1985. begin
  1986. result:=0;
  1987. exit;
  1988. end;
  1989. if (highrange>0) and (lowrange<0) then
  1990. begin
  1991. qhigh:=highrange;
  1992. qlow:=qword(-lowrange);
  1993. { prevent overflow, return 0 to indicate overflow }
  1994. if qhigh+qlow>qword(high(aint)-1) then
  1995. result:=0
  1996. else
  1997. result:=qhigh+qlow+1;
  1998. end
  1999. else
  2000. result:=int64(highrange)-lowrange+1;
  2001. end;
  2002. function tarraydef.size : aint;
  2003. var
  2004. cachedelecount : aword;
  2005. cachedelesize : aint;
  2006. begin
  2007. if ado_IsDynamicArray in arrayoptions then
  2008. begin
  2009. size:=sizeof(pint);
  2010. exit;
  2011. end;
  2012. { Tarraydef.size may never be called for an open array! }
  2013. if highrange<lowrange then
  2014. internalerror(99080501);
  2015. if not (ado_IsBitPacked in arrayoptions) then
  2016. cachedelesize:=elesize
  2017. else
  2018. cachedelesize := elepackedbitsize;
  2019. cachedelecount:=elecount;
  2020. if (cachedelesize = 0) then
  2021. begin
  2022. size := 0;
  2023. exit;
  2024. end;
  2025. if (cachedelecount = 0) then
  2026. begin
  2027. size := -1;
  2028. exit;
  2029. end;
  2030. { prevent overflow, return -1 to indicate overflow }
  2031. { also make sure we don't need 64/128 bit arithmetic to calculate offsets }
  2032. if (cachedelecount > high(aint)) or
  2033. ((high(aint) div cachedelesize) < aint(cachedelecount)) or
  2034. { also lowrange*elesize must be < high(aint) to prevent overflow when
  2035. accessing the array, see ncgmem (PFV) }
  2036. ((high(aint) div cachedelesize) < abs(lowrange)) then
  2037. begin
  2038. result:=-1;
  2039. exit;
  2040. end;
  2041. result:=cachedelesize*aint(cachedelecount);
  2042. if (ado_IsBitPacked in arrayoptions) then
  2043. { can't just add 7 and divide by 8, because that may overflow }
  2044. result:=result div 8 + ord((result mod 8)<>0);
  2045. end;
  2046. procedure tarraydef.setelementdef(def:tdef);
  2047. begin
  2048. _elementdef:=def;
  2049. if not(
  2050. (ado_IsDynamicArray in arrayoptions) or
  2051. (ado_IsConvertedPointer in arrayoptions) or
  2052. (highrange<lowrange)
  2053. ) and
  2054. (size=-1) then
  2055. Message(sym_e_segment_too_large);
  2056. end;
  2057. function tarraydef.alignment : shortint;
  2058. begin
  2059. { alignment of dyn. arrays doesn't depend on the element size }
  2060. if (ado_IsDynamicArray in arrayoptions) then
  2061. alignment:=size_2_align(sizeof(pint))
  2062. { alignment is the alignment of the elements }
  2063. else if (elementdef.typ in [arraydef,recorddef,orddef,enumdef,floatdef]) or
  2064. ((elementdef.typ=objectdef) and
  2065. is_object(elementdef)) then
  2066. alignment:=elementdef.alignment
  2067. { alignment is the size of the elements }
  2068. else if not (ado_IsBitPacked in arrayoptions) then
  2069. alignment:=size_2_align(elesize)
  2070. else
  2071. alignment:=packedbitsloadsize(elepackedbitsize);
  2072. end;
  2073. function tarraydef.needs_inittable : boolean;
  2074. begin
  2075. needs_inittable:=(ado_IsDynamicArray in arrayoptions) or elementdef.needs_inittable;
  2076. end;
  2077. function tarraydef.GetTypeName : string;
  2078. begin
  2079. if (ado_IsConstString in arrayoptions) then
  2080. result:='Constant String'
  2081. else if (ado_isarrayofconst in arrayoptions) or
  2082. (ado_isConstructor in arrayoptions) then
  2083. begin
  2084. if (ado_isvariant in arrayoptions) or ((highrange=-1) and (lowrange=0)) then
  2085. GetTypeName:='Array Of Const'
  2086. else
  2087. GetTypeName:='Array Of Const/Constant Open Array of '+elementdef.typename;
  2088. end
  2089. else if (ado_IsDynamicArray in arrayoptions) then
  2090. GetTypeName:='Dynamic Array Of '+elementdef.typename
  2091. else if ((highrange=-1) and (lowrange=0)) then
  2092. GetTypeName:='Open Array Of '+elementdef.typename
  2093. else
  2094. begin
  2095. result := '';
  2096. if (ado_IsBitPacked in arrayoptions) then
  2097. result:='Packed ';
  2098. if rangedef.typ=enumdef then
  2099. result:=result+'Array['+rangedef.typename+'] Of '+elementdef.typename
  2100. else
  2101. result:=result+'Array['+tostr(lowrange)+'..'+
  2102. tostr(highrange)+'] Of '+elementdef.typename
  2103. end;
  2104. end;
  2105. function tarraydef.getmangledparaname : string;
  2106. begin
  2107. if ado_isarrayofconst in arrayoptions then
  2108. getmangledparaname:='array_of_const'
  2109. else
  2110. if ((highrange=-1) and (lowrange=0)) then
  2111. getmangledparaname:='array_of_'+elementdef.mangledparaname
  2112. else
  2113. internalerror(200204176);
  2114. end;
  2115. function tarraydef.is_publishable : boolean;
  2116. begin
  2117. Result:=ado_IsDynamicArray in arrayoptions;
  2118. end;
  2119. {***************************************************************************
  2120. tabstractrecorddef
  2121. ***************************************************************************}
  2122. function tabstractrecorddef.GetSymtable(t:tGetSymtable):TSymtable;
  2123. begin
  2124. if t=gs_record then
  2125. GetSymtable:=symtable
  2126. else
  2127. GetSymtable:=nil;
  2128. end;
  2129. procedure tabstractrecorddef.reset;
  2130. begin
  2131. inherited reset;
  2132. tstoredsymtable(symtable).reset_all_defs;
  2133. end;
  2134. function tabstractrecorddef.is_packed:boolean;
  2135. begin
  2136. result:=tabstractrecordsymtable(symtable).is_packed;
  2137. end;
  2138. {***************************************************************************
  2139. trecorddef
  2140. ***************************************************************************}
  2141. constructor trecorddef.create(p : TSymtable);
  2142. begin
  2143. inherited create(recorddef);
  2144. symtable:=p;
  2145. { we can own the symtable only if nobody else owns a copy so far }
  2146. if symtable.refcount=1 then
  2147. symtable.defowner:=self;
  2148. isunion:=false;
  2149. end;
  2150. constructor trecorddef.ppuload(ppufile:tcompilerppufile);
  2151. begin
  2152. inherited ppuload(recorddef,ppufile);
  2153. if df_copied_def in defoptions then
  2154. ppufile.getderef(cloneddefderef)
  2155. else
  2156. begin
  2157. symtable:=trecordsymtable.create(0);
  2158. trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
  2159. trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
  2160. trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
  2161. trecordsymtable(symtable).usefieldalignment:=shortint(ppufile.getbyte);
  2162. trecordsymtable(symtable).datasize:=ppufile.getaint;
  2163. trecordsymtable(symtable).ppuload(ppufile);
  2164. { requires usefieldalignment to be set }
  2165. symtable.defowner:=self;
  2166. end;
  2167. isunion:=false;
  2168. end;
  2169. destructor trecorddef.destroy;
  2170. begin
  2171. if assigned(symtable) then
  2172. begin
  2173. symtable.free;
  2174. symtable:=nil;
  2175. end;
  2176. inherited destroy;
  2177. end;
  2178. function trecorddef.getcopy : tstoreddef;
  2179. begin
  2180. result:=trecorddef.create(symtable.getcopy);
  2181. trecorddef(result).isunion:=isunion;
  2182. include(trecorddef(result).defoptions,df_copied_def);
  2183. end;
  2184. function trecorddef.needs_inittable : boolean;
  2185. begin
  2186. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2187. end;
  2188. procedure trecorddef.buildderef;
  2189. begin
  2190. inherited buildderef;
  2191. if df_copied_def in defoptions then
  2192. cloneddefderef.build(symtable.defowner)
  2193. else
  2194. tstoredsymtable(symtable).buildderef;
  2195. end;
  2196. procedure trecorddef.deref;
  2197. begin
  2198. inherited deref;
  2199. { now dereference the definitions }
  2200. if df_copied_def in defoptions then
  2201. begin
  2202. cloneddef:=trecorddef(cloneddefderef.resolve);
  2203. symtable:=cloneddef.symtable.getcopy;
  2204. end
  2205. else
  2206. tstoredsymtable(symtable).deref;
  2207. { assign TGUID? load only from system unit }
  2208. if not(assigned(rec_tguid)) and
  2209. (upper(typename)='TGUID') and
  2210. assigned(owner) and
  2211. assigned(owner.name) and
  2212. (owner.name^='SYSTEM') then
  2213. rec_tguid:=self;
  2214. end;
  2215. procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
  2216. begin
  2217. inherited ppuwrite(ppufile);
  2218. if df_copied_def in defoptions then
  2219. ppufile.putderef(cloneddefderef)
  2220. else
  2221. begin
  2222. ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
  2223. ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
  2224. ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
  2225. ppufile.putbyte(byte(trecordsymtable(symtable).usefieldalignment));
  2226. ppufile.putaint(trecordsymtable(symtable).datasize);
  2227. end;
  2228. ppufile.writeentry(ibrecorddef);
  2229. if not(df_copied_def in defoptions) then
  2230. trecordsymtable(symtable).ppuwrite(ppufile);
  2231. end;
  2232. function trecorddef.size:aint;
  2233. begin
  2234. result:=trecordsymtable(symtable).datasize;
  2235. end;
  2236. function trecorddef.alignment:shortint;
  2237. begin
  2238. alignment:=trecordsymtable(symtable).recordalignment;
  2239. end;
  2240. function trecorddef.padalignment:shortint;
  2241. begin
  2242. padalignment := trecordsymtable(symtable).padalignment;
  2243. end;
  2244. function trecorddef.GetTypeName : string;
  2245. begin
  2246. GetTypeName:='<record type>'
  2247. end;
  2248. {***************************************************************************
  2249. TABSTRACTPROCDEF
  2250. ***************************************************************************}
  2251. constructor tabstractprocdef.create(dt:tdeftyp;level:byte);
  2252. begin
  2253. inherited create(dt);
  2254. parast:=tparasymtable.create(self,level);
  2255. paras:=nil;
  2256. minparacount:=0;
  2257. maxparacount:=0;
  2258. proctypeoption:=potype_none;
  2259. proccalloption:=pocall_none;
  2260. procoptions:=[];
  2261. returndef:=voidtype;
  2262. savesize:=sizeof(pint);
  2263. requiredargarea:=0;
  2264. has_paraloc_info:=false;
  2265. location_reset(funcretloc[callerside],LOC_INVALID,OS_NO);
  2266. location_reset(funcretloc[calleeside],LOC_INVALID,OS_NO);
  2267. end;
  2268. destructor tabstractprocdef.destroy;
  2269. begin
  2270. if assigned(paras) then
  2271. begin
  2272. {$ifdef MEMDEBUG}
  2273. memprocpara.start;
  2274. {$endif MEMDEBUG}
  2275. paras.free;
  2276. paras:=nil;
  2277. {$ifdef MEMDEBUG}
  2278. memprocpara.stop;
  2279. {$endif MEMDEBUG}
  2280. end;
  2281. if assigned(parast) then
  2282. begin
  2283. {$ifdef MEMDEBUG}
  2284. memprocparast.start;
  2285. {$endif MEMDEBUG}
  2286. parast.free;
  2287. parast:=nil;
  2288. {$ifdef MEMDEBUG}
  2289. memprocparast.stop;
  2290. {$endif MEMDEBUG}
  2291. end;
  2292. inherited destroy;
  2293. end;
  2294. procedure tabstractprocdef.count_para(p:TObject;arg:pointer);
  2295. begin
  2296. if (tsym(p).typ<>paravarsym) then
  2297. exit;
  2298. inc(plongint(arg)^);
  2299. if not(vo_is_hidden_para in tparavarsym(p).varoptions) then
  2300. begin
  2301. if not assigned(tparavarsym(p).defaultconstsym) then
  2302. inc(minparacount);
  2303. inc(maxparacount);
  2304. end;
  2305. end;
  2306. procedure tabstractprocdef.insert_para(p:TObject;arg:pointer);
  2307. begin
  2308. if (tsym(p).typ<>paravarsym) then
  2309. exit;
  2310. paras.add(p);
  2311. end;
  2312. procedure tabstractprocdef.calcparas;
  2313. var
  2314. paracount : longint;
  2315. begin
  2316. { This can already be assigned when
  2317. we need to reresolve this unit (PFV) }
  2318. if assigned(paras) then
  2319. paras.free;
  2320. paras:=tparalist.create(false);
  2321. paracount:=0;
  2322. minparacount:=0;
  2323. maxparacount:=0;
  2324. parast.SymList.ForEachCall(@count_para,@paracount);
  2325. paras.capacity:=paracount;
  2326. { Insert parameters in table }
  2327. parast.SymList.ForEachCall(@insert_para,nil);
  2328. { Order parameters }
  2329. paras.sortparas;
  2330. end;
  2331. procedure tabstractprocdef.buildderef;
  2332. begin
  2333. { released procdef? }
  2334. if not assigned(parast) then
  2335. exit;
  2336. inherited buildderef;
  2337. returndefderef.build(returndef);
  2338. { parast }
  2339. tparasymtable(parast).buildderef;
  2340. end;
  2341. procedure tabstractprocdef.deref;
  2342. begin
  2343. inherited deref;
  2344. returndef:=tdef(returndefderef.resolve);
  2345. { parast }
  2346. tparasymtable(parast).deref;
  2347. { recalculated parameters }
  2348. calcparas;
  2349. end;
  2350. constructor tabstractprocdef.ppuload(dt:tdeftyp;ppufile:tcompilerppufile);
  2351. var
  2352. b : byte;
  2353. begin
  2354. inherited ppuload(dt,ppufile);
  2355. parast:=nil;
  2356. Paras:=nil;
  2357. minparacount:=0;
  2358. maxparacount:=0;
  2359. ppufile.getderef(returndefderef);
  2360. { TODO: remove fpu_used loading}
  2361. ppufile.getbyte;
  2362. proctypeoption:=tproctypeoption(ppufile.getbyte);
  2363. proccalloption:=tproccalloption(ppufile.getbyte);
  2364. ppufile.getnormalset(procoptions);
  2365. location_reset(funcretloc[callerside],LOC_INVALID,OS_NO);
  2366. location_reset(funcretloc[calleeside],LOC_INVALID,OS_NO);
  2367. if po_explicitparaloc in procoptions then
  2368. begin
  2369. b:=ppufile.getbyte;
  2370. if b<>sizeof(funcretloc[callerside]) then
  2371. internalerror(200411154);
  2372. ppufile.getdata(funcretloc[callerside],sizeof(funcretloc[callerside]));
  2373. end;
  2374. savesize:=sizeof(pint);
  2375. has_paraloc_info:=(po_explicitparaloc in procoptions);
  2376. end;
  2377. procedure tabstractprocdef.ppuwrite(ppufile:tcompilerppufile);
  2378. var
  2379. oldintfcrc : boolean;
  2380. begin
  2381. { released procdef? }
  2382. if not assigned(parast) then
  2383. exit;
  2384. inherited ppuwrite(ppufile);
  2385. ppufile.putderef(returndefderef);
  2386. oldintfcrc:=ppufile.do_interface_crc;
  2387. ppufile.do_interface_crc:=false;
  2388. ppufile.putbyte(0);
  2389. ppufile.putbyte(ord(proctypeoption));
  2390. ppufile.putbyte(ord(proccalloption));
  2391. ppufile.putnormalset(procoptions);
  2392. ppufile.do_interface_crc:=oldintfcrc;
  2393. if (po_explicitparaloc in procoptions) then
  2394. begin
  2395. { Make a 'valid' funcretloc for procedures }
  2396. ppufile.putbyte(sizeof(funcretloc[callerside]));
  2397. ppufile.putdata(funcretloc[callerside],sizeof(funcretloc[callerside]));
  2398. end;
  2399. end;
  2400. function tabstractprocdef.typename_paras(showhidden:boolean) : string;
  2401. var
  2402. hs,s : string;
  2403. hp : TParavarsym;
  2404. hpc : tconstsym;
  2405. first : boolean;
  2406. i : integer;
  2407. begin
  2408. s:='';
  2409. first:=true;
  2410. for i:=0 to paras.count-1 do
  2411. begin
  2412. hp:=tparavarsym(paras[i]);
  2413. if not(vo_is_hidden_para in hp.varoptions) or
  2414. (showhidden) then
  2415. begin
  2416. if first then
  2417. begin
  2418. s:=s+'(';
  2419. first:=false;
  2420. end
  2421. else
  2422. s:=s+',';
  2423. if vo_is_hidden_para in hp.varoptions then
  2424. s:=s+'<';
  2425. case hp.varspez of
  2426. vs_var :
  2427. s:=s+'var ';
  2428. vs_const :
  2429. s:=s+'const ';
  2430. vs_out :
  2431. s:=s+'out ';
  2432. end;
  2433. if assigned(hp.vardef.typesym) then
  2434. begin
  2435. hs:=hp.vardef.typesym.realname;
  2436. if hs[1]<>'$' then
  2437. s:=s+hs
  2438. else
  2439. s:=s+hp.vardef.GetTypeName;
  2440. end
  2441. else
  2442. s:=s+hp.vardef.GetTypeName;
  2443. { default value }
  2444. if assigned(hp.defaultconstsym) then
  2445. begin
  2446. hpc:=tconstsym(hp.defaultconstsym);
  2447. hs:='';
  2448. case hpc.consttyp of
  2449. conststring,
  2450. constresourcestring :
  2451. begin
  2452. If hpc.value.len>0 then
  2453. begin
  2454. setLength(hs,hpc.value.len);
  2455. move(hpc.value.valueptr^,hs[1],hpc.value.len);
  2456. end;
  2457. end;
  2458. constreal :
  2459. str(pbestreal(hpc.value.valueptr)^,hs);
  2460. constpointer :
  2461. hs:=tostr(hpc.value.valueordptr);
  2462. constord :
  2463. begin
  2464. if is_boolean(hpc.constdef) then
  2465. begin
  2466. if hpc.value.valueord<>0 then
  2467. hs:='TRUE'
  2468. else
  2469. hs:='FALSE';
  2470. end
  2471. else
  2472. hs:=tostr(hpc.value.valueord);
  2473. end;
  2474. constnil :
  2475. hs:='nil';
  2476. constset :
  2477. hs:='<set>';
  2478. end;
  2479. if hs<>'' then
  2480. s:=s+'="'+hs+'"';
  2481. end;
  2482. if vo_is_hidden_para in hp.varoptions then
  2483. s:=s+'>';
  2484. end;
  2485. end;
  2486. if not first then
  2487. s:=s+')';
  2488. if (po_varargs in procoptions) then
  2489. s:=s+';VarArgs';
  2490. typename_paras:=s;
  2491. end;
  2492. function tabstractprocdef.is_methodpointer:boolean;
  2493. begin
  2494. result:=false;
  2495. end;
  2496. function tabstractprocdef.is_addressonly:boolean;
  2497. begin
  2498. result:=true;
  2499. end;
  2500. {***************************************************************************
  2501. TPROCDEF
  2502. ***************************************************************************}
  2503. constructor tprocdef.create(level:byte);
  2504. begin
  2505. inherited create(procdef,level);
  2506. localst:=tlocalsymtable.create(self,parast.symtablelevel);
  2507. _mangledname:=nil;
  2508. fileinfo:=current_filepos;
  2509. extnumber:=$ffff;
  2510. aliasnames:=TCmdStrList.create;
  2511. funcretsym:=nil;
  2512. forwarddef:=true;
  2513. interfacedef:=false;
  2514. hasforward:=false;
  2515. _class := nil;
  2516. import_dll:=nil;
  2517. import_name:=nil;
  2518. import_nr:=0;
  2519. inlininginfo:=nil;
  2520. {$ifdef i386}
  2521. fpu_used:=maxfpuregs;
  2522. {$endif i386}
  2523. end;
  2524. constructor tprocdef.ppuload(ppufile:tcompilerppufile);
  2525. var
  2526. i,aliasnamescount : longint;
  2527. level : byte;
  2528. begin
  2529. inherited ppuload(procdef,ppufile);
  2530. if po_has_mangledname in procoptions then
  2531. _mangledname:=stringdup(ppufile.getstring)
  2532. else
  2533. _mangledname:=nil;
  2534. extnumber:=ppufile.getword;
  2535. level:=ppufile.getbyte;
  2536. ppufile.getderef(_classderef);
  2537. ppufile.getderef(procsymderef);
  2538. ppufile.getposinfo(fileinfo);
  2539. visibility:=tvisibility(ppufile.getbyte);
  2540. ppufile.getsmallset(symoptions);
  2541. {$ifdef powerpc}
  2542. { library symbol for AmigaOS/MorphOS }
  2543. ppufile.getderef(libsymderef);
  2544. {$endif powerpc}
  2545. { import stuff }
  2546. if po_has_importdll in procoptions then
  2547. import_dll:=stringdup(ppufile.getstring)
  2548. else
  2549. import_dll:=nil;
  2550. if po_has_importname in procoptions then
  2551. import_name:=stringdup(ppufile.getstring)
  2552. else
  2553. import_name:=nil;
  2554. import_nr:=ppufile.getword;
  2555. if (po_msgint in procoptions) then
  2556. messageinf.i:=ppufile.getlongint;
  2557. if (po_msgstr in procoptions) then
  2558. messageinf.str:=stringdup(ppufile.getstring);
  2559. if (po_dispid in procoptions) then
  2560. dispid:=ppufile.getlongint;
  2561. { inline stuff }
  2562. if (po_has_inlininginfo in procoptions) then
  2563. begin
  2564. ppufile.getderef(funcretsymderef);
  2565. new(inlininginfo);
  2566. ppufile.getsmallset(inlininginfo^.flags);
  2567. end
  2568. else
  2569. begin
  2570. inlininginfo:=nil;
  2571. funcretsym:=nil;
  2572. end;
  2573. aliasnames:=TCmdStrList.create;
  2574. { count alias names }
  2575. aliasnamescount:=ppufile.getbyte;
  2576. for i:=1 to aliasnamescount do
  2577. aliasnames.insert(ppufile.getstring);
  2578. { load para symtable }
  2579. parast:=tparasymtable.create(self,level);
  2580. tparasymtable(parast).ppuload(ppufile);
  2581. { load local symtable }
  2582. if (po_has_inlininginfo in procoptions) then
  2583. begin
  2584. localst:=tlocalsymtable.create(self,level);
  2585. tlocalsymtable(localst).ppuload(ppufile);
  2586. end
  2587. else
  2588. localst:=nil;
  2589. { inline stuff }
  2590. if (po_has_inlininginfo in procoptions) then
  2591. inlininginfo^.code:=ppuloadnodetree(ppufile);
  2592. { default values for no persistent data }
  2593. if (cs_link_deffile in current_settings.globalswitches) and
  2594. (tf_need_export in target_info.flags) and
  2595. (po_exports in procoptions) then
  2596. deffile.AddExport(mangledname);
  2597. forwarddef:=false;
  2598. interfacedef:=false;
  2599. hasforward:=false;
  2600. { Disable po_has_inlining until the derefimpl is done }
  2601. exclude(procoptions,po_has_inlininginfo);
  2602. {$ifdef i386}
  2603. fpu_used:=maxfpuregs;
  2604. {$endif i386}
  2605. end;
  2606. destructor tprocdef.destroy;
  2607. begin
  2608. aliasnames.free;
  2609. aliasnames:=nil;
  2610. if assigned(localst) and
  2611. (localst.symtabletype<>staticsymtable) then
  2612. begin
  2613. {$ifdef MEMDEBUG}
  2614. memproclocalst.start;
  2615. {$endif MEMDEBUG}
  2616. localst.free;
  2617. localst:=nil;
  2618. {$ifdef MEMDEBUG}
  2619. memproclocalst.start;
  2620. {$endif MEMDEBUG}
  2621. end;
  2622. if assigned(inlininginfo) then
  2623. begin
  2624. {$ifdef MEMDEBUG}
  2625. memprocnodetree.start;
  2626. {$endif MEMDEBUG}
  2627. tnode(inlininginfo^.code).free;
  2628. {$ifdef MEMDEBUG}
  2629. memprocnodetree.start;
  2630. {$endif MEMDEBUG}
  2631. dispose(inlininginfo);
  2632. inlininginfo:=nil;
  2633. end;
  2634. stringdispose(resultname);
  2635. stringdispose(import_dll);
  2636. stringdispose(import_name);
  2637. if (po_msgstr in procoptions) then
  2638. stringdispose(messageinf.str);
  2639. if assigned(_mangledname) then
  2640. begin
  2641. {$ifdef MEMDEBUG}
  2642. memmanglednames.start;
  2643. {$endif MEMDEBUG}
  2644. stringdispose(_mangledname);
  2645. {$ifdef MEMDEBUG}
  2646. memmanglednames.stop;
  2647. {$endif MEMDEBUG}
  2648. end;
  2649. inherited destroy;
  2650. end;
  2651. procedure tprocdef.ppuwrite(ppufile:tcompilerppufile);
  2652. var
  2653. oldintfcrc : boolean;
  2654. aliasnamescount : longint;
  2655. item : TCmdStrListItem;
  2656. begin
  2657. { released procdef? }
  2658. if not assigned(parast) then
  2659. exit;
  2660. inherited ppuwrite(ppufile);
  2661. if po_has_mangledname in procoptions then
  2662. ppufile.putstring(_mangledname^);
  2663. ppufile.putword(extnumber);
  2664. ppufile.putbyte(parast.symtablelevel);
  2665. ppufile.putderef(_classderef);
  2666. ppufile.putderef(procsymderef);
  2667. ppufile.putposinfo(fileinfo);
  2668. ppufile.putbyte(byte(visibility));
  2669. ppufile.putsmallset(symoptions);
  2670. {$ifdef powerpc}
  2671. { library symbol for AmigaOS/MorphOS }
  2672. ppufile.putderef(libsymderef);
  2673. {$endif powerpc}
  2674. { import }
  2675. if po_has_importdll in procoptions then
  2676. ppufile.putstring(import_dll^);
  2677. if po_has_importname in procoptions then
  2678. ppufile.putstring(import_name^);
  2679. ppufile.putword(import_nr);
  2680. if (po_msgint in procoptions) then
  2681. ppufile.putlongint(messageinf.i);
  2682. if (po_msgstr in procoptions) then
  2683. ppufile.putstring(messageinf.str^);
  2684. if (po_dispid in procoptions) then
  2685. ppufile.putlongint(dispid);
  2686. { inline stuff }
  2687. oldintfcrc:=ppufile.do_crc;
  2688. ppufile.do_crc:=false;
  2689. if (po_has_inlininginfo in procoptions) then
  2690. begin
  2691. ppufile.putderef(funcretsymderef);
  2692. ppufile.putsmallset(inlininginfo^.flags);
  2693. end;
  2694. { count alias names }
  2695. aliasnamescount:=0;
  2696. item:=TCmdStrListItem(aliasnames.first);
  2697. while assigned(item) do
  2698. begin
  2699. inc(aliasnamescount);
  2700. item:=TCmdStrListItem(item.next);
  2701. end;
  2702. if aliasnamescount>255 then
  2703. internalerror(200711021);
  2704. ppufile.putbyte(aliasnamescount);
  2705. item:=TCmdStrListItem(aliasnames.first);
  2706. while assigned(item) do
  2707. begin
  2708. ppufile.putstring(item.str);
  2709. item:=TCmdStrListItem(item.next);
  2710. end;
  2711. ppufile.do_crc:=oldintfcrc;
  2712. { write this entry }
  2713. ppufile.writeentry(ibprocdef);
  2714. { Save the para symtable, this is taken from the interface }
  2715. tparasymtable(parast).ppuwrite(ppufile);
  2716. { save localsymtable for inline procedures or when local
  2717. browser info is requested, this has no influence on the crc }
  2718. if (po_has_inlininginfo in procoptions) then
  2719. begin
  2720. oldintfcrc:=ppufile.do_crc;
  2721. ppufile.do_crc:=false;
  2722. tlocalsymtable(localst).ppuwrite(ppufile);
  2723. ppufile.do_crc:=oldintfcrc;
  2724. end;
  2725. { node tree for inlining }
  2726. oldintfcrc:=ppufile.do_crc;
  2727. ppufile.do_crc:=false;
  2728. if (po_has_inlininginfo in procoptions) then
  2729. ppuwritenodetree(ppufile,inlininginfo^.code);
  2730. ppufile.do_crc:=oldintfcrc;
  2731. end;
  2732. procedure tprocdef.reset;
  2733. begin
  2734. inherited reset;
  2735. procstarttai:=nil;
  2736. procendtai:=nil;
  2737. end;
  2738. function tprocdef.fullprocname(showhidden:boolean):string;
  2739. var
  2740. s : string;
  2741. t : ttoken;
  2742. begin
  2743. {$ifdef EXTDEBUG}
  2744. showhidden:=true;
  2745. {$endif EXTDEBUG}
  2746. s:='';
  2747. if owner.symtabletype=localsymtable then
  2748. s:=s+'local ';
  2749. if assigned(_class) then
  2750. begin
  2751. if po_classmethod in procoptions then
  2752. s:=s+'class ';
  2753. s:=s+_class.objrealname^+'.';
  2754. end;
  2755. if proctypeoption=potype_operator then
  2756. begin
  2757. for t:=NOTOKEN to last_overloaded do
  2758. if procsym.realname='$'+overloaded_names[t] then
  2759. begin
  2760. s:='operator '+arraytokeninfo[t].str+typename_paras(showhidden);
  2761. break;
  2762. end;
  2763. end
  2764. else
  2765. s:=s+procsym.realname+typename_paras(showhidden);
  2766. case proctypeoption of
  2767. potype_constructor:
  2768. s:='constructor '+s;
  2769. potype_destructor:
  2770. s:='destructor '+s;
  2771. else
  2772. if assigned(returndef) and
  2773. not(is_void(returndef)) then
  2774. s:=s+':'+returndef.GetTypeName;
  2775. end;
  2776. s:=s+';';
  2777. { forced calling convention? }
  2778. if (po_hascallingconvention in procoptions) then
  2779. s:=s+' '+ProcCallOptionStr[proccalloption]+';';
  2780. if po_staticmethod in procoptions then
  2781. s:=s+' Static;';
  2782. fullprocname:=s;
  2783. end;
  2784. function tprocdef.is_methodpointer:boolean;
  2785. begin
  2786. result:=assigned(_class);
  2787. end;
  2788. function tprocdef.is_addressonly:boolean;
  2789. begin
  2790. result:=assigned(owner) and
  2791. (owner.symtabletype<>ObjectSymtable);
  2792. end;
  2793. function tprocdef.GetSymtable(t:tGetSymtable):TSymtable;
  2794. begin
  2795. case t of
  2796. gs_local :
  2797. GetSymtable:=localst;
  2798. gs_para :
  2799. GetSymtable:=parast;
  2800. else
  2801. GetSymtable:=nil;
  2802. end;
  2803. end;
  2804. procedure tprocdef.buildderef;
  2805. begin
  2806. inherited buildderef;
  2807. _classderef.build(_class);
  2808. { procsym that originaly defined this definition, should be in the
  2809. same symtable }
  2810. procsymderef.build(procsym);
  2811. {$ifdef powerpc}
  2812. { library symbol for AmigaOS/MorphOS }
  2813. libsymderef.build(libsym);
  2814. {$endif powerpc}
  2815. end;
  2816. procedure tprocdef.buildderefimpl;
  2817. begin
  2818. inherited buildderefimpl;
  2819. { Localst is not available for main/unit init }
  2820. if assigned(localst) then
  2821. begin
  2822. tlocalsymtable(localst).buildderef;
  2823. tlocalsymtable(localst).buildderefimpl;
  2824. end;
  2825. { inline tree }
  2826. if (po_has_inlininginfo in procoptions) then
  2827. begin
  2828. funcretsymderef.build(funcretsym);
  2829. inlininginfo^.code.buildderefimpl;
  2830. end;
  2831. end;
  2832. procedure tprocdef.deref;
  2833. begin
  2834. inherited deref;
  2835. _class:=tobjectdef(_classderef.resolve);
  2836. { procsym that originaly defined this definition, should be in the
  2837. same symtable }
  2838. procsym:=tprocsym(procsymderef.resolve);
  2839. {$ifdef powerpc}
  2840. { library symbol for AmigaOS/MorphOS }
  2841. libsym:=tsym(libsymderef.resolve);
  2842. {$endif powerpc}
  2843. end;
  2844. procedure tprocdef.derefimpl;
  2845. begin
  2846. { Enable has_inlininginfo when the inlininginfo
  2847. structure is available. The has_inlininginfo was disabled
  2848. after the load, since the data was invalid }
  2849. if assigned(inlininginfo) then
  2850. include(procoptions,po_has_inlininginfo);
  2851. { Locals }
  2852. if assigned(localst) then
  2853. begin
  2854. tlocalsymtable(localst).deref;
  2855. tlocalsymtable(localst).derefimpl;
  2856. end;
  2857. { Inline }
  2858. if (po_has_inlininginfo in procoptions) then
  2859. begin
  2860. inlininginfo^.code.derefimpl;
  2861. { funcretsym, this is always located in the localst }
  2862. funcretsym:=tsym(funcretsymderef.resolve);
  2863. end
  2864. else
  2865. begin
  2866. { safety }
  2867. funcretsym:=nil;
  2868. end;
  2869. end;
  2870. function tprocdef.GetTypeName : string;
  2871. begin
  2872. GetTypeName := FullProcName(false);
  2873. end;
  2874. function tprocdef.mangledname : string;
  2875. var
  2876. hp : TParavarsym;
  2877. hs : string;
  2878. crc : dword;
  2879. newlen,
  2880. oldlen,
  2881. i : integer;
  2882. begin
  2883. if assigned(_mangledname) then
  2884. begin
  2885. {$ifdef compress}
  2886. mangledname:=minilzw_decode(_mangledname^);
  2887. {$else}
  2888. mangledname:=_mangledname^;
  2889. {$endif}
  2890. exit;
  2891. end;
  2892. { we need to use the symtable where the procsym is inserted,
  2893. because that is visible to the world }
  2894. mangledname:=make_mangledname('',procsym.owner,procsym.name);
  2895. oldlen:=length(mangledname);
  2896. { add parameter types }
  2897. for i:=0 to paras.count-1 do
  2898. begin
  2899. hp:=tparavarsym(paras[i]);
  2900. if not(vo_is_hidden_para in hp.varoptions) then
  2901. mangledname:=mangledname+'$'+hp.vardef.mangledparaname;
  2902. end;
  2903. { add resultdef, add $$ as separator to make it unique from a
  2904. parameter separator }
  2905. if not is_void(returndef) then
  2906. mangledname:=mangledname+'$$'+returndef.mangledparaname;
  2907. newlen:=length(mangledname);
  2908. { Replace with CRC if the parameter line is very long }
  2909. if (newlen-oldlen>12) and
  2910. ((newlen>128) or (newlen-oldlen>64)) then
  2911. begin
  2912. crc:=0;
  2913. for i:=0 to paras.count-1 do
  2914. begin
  2915. hp:=tparavarsym(paras[i]);
  2916. if not(vo_is_hidden_para in hp.varoptions) then
  2917. begin
  2918. hs:=hp.vardef.mangledparaname;
  2919. crc:=UpdateCrc32(crc,hs[1],length(hs));
  2920. end;
  2921. end;
  2922. hs:=hp.vardef.mangledparaname;
  2923. crc:=UpdateCrc32(crc,hs[1],length(hs));
  2924. mangledname:=Copy(mangledname,1,oldlen)+'$crc'+hexstr(crc,8);
  2925. end;
  2926. {$ifdef compress}
  2927. _mangledname:=stringdup(minilzw_encode(mangledname));
  2928. {$else}
  2929. _mangledname:=stringdup(mangledname);
  2930. {$endif}
  2931. end;
  2932. function tprocdef.cplusplusmangledname : string;
  2933. function getcppparaname(p : tdef) : string;
  2934. const
  2935. ordtype2str : array[tordtype] of string[2] = (
  2936. '',
  2937. 'Uc','Us','Ui','Us',
  2938. 'Sc','s','i','x',
  2939. 'b','b','b','b','b',
  2940. 'c','w','x');
  2941. var
  2942. s : string;
  2943. begin
  2944. case p.typ of
  2945. orddef:
  2946. s:=ordtype2str[torddef(p).ordtype];
  2947. pointerdef:
  2948. s:='P'+getcppparaname(tpointerdef(p).pointeddef);
  2949. else
  2950. internalerror(2103001);
  2951. end;
  2952. getcppparaname:=s;
  2953. end;
  2954. var
  2955. s,s2 : string;
  2956. hp : TParavarsym;
  2957. i : integer;
  2958. begin
  2959. { outdated gcc 2.x name mangling scheme }
  2960. {$ifdef NAMEMANGLING_GCC2}
  2961. s := procsym.realname;
  2962. if procsym.owner.symtabletype=ObjectSymtable then
  2963. begin
  2964. s2:=upper(tobjectdef(procsym.owner.defowner).objrealname^);
  2965. case proctypeoption of
  2966. potype_destructor:
  2967. s:='_$_'+tostr(length(s2))+s2;
  2968. potype_constructor:
  2969. s:='___'+tostr(length(s2))+s2;
  2970. else
  2971. s:='_'+s+'__'+tostr(length(s2))+s2;
  2972. end;
  2973. end
  2974. else s:=s+'__';
  2975. s:=s+'F';
  2976. { concat modifiers }
  2977. { !!!!! }
  2978. { now we handle the parameters }
  2979. if maxparacount>0 then
  2980. begin
  2981. for i:=0 to paras.count-1 do
  2982. begin
  2983. hp:=tparavarsym(paras[i]);
  2984. s2:=getcppparaname(hp.vardef);
  2985. if hp.varspez in [vs_var,vs_out] then
  2986. s2:='R'+s2;
  2987. s:=s+s2;
  2988. end;
  2989. end
  2990. else
  2991. s:=s+'v';
  2992. cplusplusmangledname:=s;
  2993. {$endif NAMEMANGLING_GCC2}
  2994. { gcc 3.x name mangling scheme }
  2995. if procsym.owner.symtabletype=ObjectSymtable then
  2996. begin
  2997. s:='_ZN';
  2998. s2:=tobjectdef(procsym.owner.defowner).objrealname^;
  2999. s:=s+tostr(length(s2))+s2;
  3000. case proctypeoption of
  3001. potype_constructor:
  3002. s:=s+'C1';
  3003. potype_destructor:
  3004. s:=s+'D1';
  3005. else
  3006. s:=s+tostr(length(procsym.realname))+procsym.realname;
  3007. end;
  3008. s:=s+'E';
  3009. end
  3010. else
  3011. s:=procsym.realname;
  3012. { now we handle the parameters }
  3013. if maxparacount>0 then
  3014. begin
  3015. for i:=0 to paras.count-1 do
  3016. begin
  3017. hp:=tparavarsym(paras[i]);
  3018. s2:=getcppparaname(hp.vardef);
  3019. if hp.varspez in [vs_var,vs_out] then
  3020. s2:='R'+s2;
  3021. s:=s+s2;
  3022. end;
  3023. end
  3024. else
  3025. s:=s+'v';
  3026. cplusplusmangledname:=s;
  3027. end;
  3028. function tprocdef.objcmangledname : string;
  3029. begin
  3030. if not (po_msgstr in procoptions) then
  3031. internalerror(2009030901);
  3032. { we may very well need longer strings to handle these... }
  3033. if ((255-length(tobjectdef(procsym.owner.defowner).objrealname^)
  3034. -length('+[ ]')-length(messageinf.str^)) < 0) then
  3035. Message1(parser_e_objc_message_name_too_long,messageinf.str^);
  3036. if not(po_classmethod in procoptions) then
  3037. result:='-['
  3038. else
  3039. result:='+[';
  3040. result:=
  3041. result+tobjectdef(procsym.owner.defowner).objrealname^+' '+
  3042. messageinf.str^+']';
  3043. end;
  3044. procedure tprocdef.setmangledname(const s : string);
  3045. begin
  3046. { This is not allowed anymore, the forward declaration
  3047. already needs to create the correct mangledname, no changes
  3048. afterwards are allowed (PFV) }
  3049. { Exception: interface definitions in mode macpas, since in that }
  3050. { case no reference to the old name can exist yet (JM) }
  3051. if assigned(_mangledname) then
  3052. if ((m_mac in current_settings.modeswitches) and
  3053. (interfacedef)) then
  3054. stringdispose(_mangledname)
  3055. else
  3056. internalerror(200411171);
  3057. {$ifdef compress}
  3058. _mangledname:=stringdup(minilzw_encode(s));
  3059. {$else}
  3060. _mangledname:=stringdup(s);
  3061. {$endif}
  3062. include(procoptions,po_has_mangledname);
  3063. end;
  3064. {***************************************************************************
  3065. TPROCVARDEF
  3066. ***************************************************************************}
  3067. constructor tprocvardef.create(level:byte);
  3068. begin
  3069. inherited create(procvardef,level);
  3070. end;
  3071. constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
  3072. begin
  3073. inherited ppuload(procvardef,ppufile);
  3074. { load para symtable }
  3075. parast:=tparasymtable.create(self,unknown_level);
  3076. tparasymtable(parast).ppuload(ppufile);
  3077. end;
  3078. function tprocvardef.getcopy : tstoreddef;
  3079. var
  3080. i : tcallercallee;
  3081. j : longint;
  3082. begin
  3083. result:=tprocvardef.create(parast.symtablelevel);
  3084. tprocvardef(result).returndef:=returndef;
  3085. tprocvardef(result).returndefderef:=returndefderef;
  3086. tprocvardef(result).parast:=parast.getcopy;
  3087. tprocvardef(result).savesize:=savesize;
  3088. { create paralist copy }
  3089. tprocvardef(result).paras:=tparalist.create(false);
  3090. tprocvardef(result).paras.count:=paras.count;
  3091. for j:=0 to paras.count-1 do
  3092. tprocvardef(result).paras[j]:=paras[j];
  3093. tprocvardef(result).proctypeoption:=proctypeoption;
  3094. tprocvardef(result).proccalloption:=proccalloption;
  3095. tprocvardef(result).procoptions:=procoptions;
  3096. tprocvardef(result).requiredargarea:=requiredargarea;
  3097. tprocvardef(result).maxparacount:=maxparacount;
  3098. tprocvardef(result).minparacount:=minparacount;
  3099. for i:=low(tcallercallee) to high(tcallercallee) do
  3100. location_copy(tprocvardef(result).funcretloc[i],funcretloc[i]);
  3101. tprocvardef(result).has_paraloc_info:=has_paraloc_info;
  3102. {$ifdef m68k}
  3103. tprocvardef(result).exp_funcretloc:=exp_funcretloc;
  3104. {$endif}
  3105. end;
  3106. procedure tprocvardef.ppuwrite(ppufile:tcompilerppufile);
  3107. begin
  3108. inherited ppuwrite(ppufile);
  3109. { Write this entry }
  3110. ppufile.writeentry(ibprocvardef);
  3111. { Save the para symtable, this is taken from the interface }
  3112. tparasymtable(parast).ppuwrite(ppufile);
  3113. end;
  3114. function tprocvardef.GetSymtable(t:tGetSymtable):TSymtable;
  3115. begin
  3116. case t of
  3117. gs_para :
  3118. GetSymtable:=parast;
  3119. else
  3120. GetSymtable:=nil;
  3121. end;
  3122. end;
  3123. function tprocvardef.size : aint;
  3124. begin
  3125. if (po_methodpointer in procoptions) and
  3126. not(po_addressonly in procoptions) then
  3127. size:=2*sizeof(pint)
  3128. else
  3129. size:=sizeof(pint);
  3130. end;
  3131. function tprocvardef.is_methodpointer:boolean;
  3132. begin
  3133. result:=(po_methodpointer in procoptions);
  3134. end;
  3135. function tprocvardef.is_addressonly:boolean;
  3136. begin
  3137. result:=not(po_methodpointer in procoptions) or
  3138. (po_addressonly in procoptions);
  3139. end;
  3140. function tprocvardef.getmangledparaname:string;
  3141. begin
  3142. result:='procvar';
  3143. end;
  3144. function tprocvardef.is_publishable : boolean;
  3145. begin
  3146. is_publishable:=(po_methodpointer in procoptions);
  3147. end;
  3148. function tprocvardef.GetTypeName : string;
  3149. var
  3150. s: string;
  3151. showhidden : boolean;
  3152. begin
  3153. {$ifdef EXTDEBUG}
  3154. showhidden:=true;
  3155. {$else EXTDEBUG}
  3156. showhidden:=false;
  3157. {$endif EXTDEBUG}
  3158. s:='<';
  3159. if po_classmethod in procoptions then
  3160. s := s+'class method type of'
  3161. else
  3162. if po_addressonly in procoptions then
  3163. s := s+'address of'
  3164. else
  3165. s := s+'procedure variable type of';
  3166. if po_local in procoptions then
  3167. s := s+' local';
  3168. if assigned(returndef) and
  3169. (returndef<>voidtype) then
  3170. s:=s+' function'+typename_paras(showhidden)+':'+returndef.GetTypeName
  3171. else
  3172. s:=s+' procedure'+typename_paras(showhidden);
  3173. if po_methodpointer in procoptions then
  3174. s := s+' of object';
  3175. GetTypeName := s+';'+ProcCallOptionStr[proccalloption]+'>';
  3176. end;
  3177. {***************************************************************************
  3178. TOBJECTDEF
  3179. ***************************************************************************}
  3180. constructor tobjectdef.create(ot : tobjecttyp;const n : string;c : tobjectdef);
  3181. begin
  3182. inherited create(objectdef);
  3183. objecttype:=ot;
  3184. objectoptions:=[];
  3185. childof:=nil;
  3186. symtable:=tObjectSymtable.create(self,n,current_settings.packrecords);
  3187. { create space for vmt !! }
  3188. vmtentries:=TFPList.Create;
  3189. vmt_offset:=0;
  3190. set_parent(c);
  3191. objname:=stringdup(upper(n));
  3192. objrealname:=stringdup(n);
  3193. if objecttype in [odt_interfacecorba,odt_interfacecom,odt_dispinterface] then
  3194. prepareguid;
  3195. { setup implemented interfaces }
  3196. if objecttype in [odt_class,odt_interfacecorba] then
  3197. ImplementedInterfaces:=TFPObjectList.Create(true)
  3198. else
  3199. ImplementedInterfaces:=nil;
  3200. writing_class_record_dbginfo:=false;
  3201. end;
  3202. constructor tobjectdef.ppuload(ppufile:tcompilerppufile);
  3203. var
  3204. i,
  3205. implintfcount : longint;
  3206. d : tderef;
  3207. ImplIntf : TImplementedInterface;
  3208. vmtentry : pvmtentry;
  3209. begin
  3210. inherited ppuload(objectdef,ppufile);
  3211. objecttype:=tobjecttyp(ppufile.getbyte);
  3212. objrealname:=stringdup(ppufile.getstring);
  3213. objname:=stringdup(upper(objrealname^));
  3214. symtable:=tObjectSymtable.create(self,objrealname^,0);
  3215. tObjectSymtable(symtable).datasize:=ppufile.getaint;
  3216. tObjectSymtable(symtable).fieldalignment:=ppufile.getbyte;
  3217. tObjectSymtable(symtable).recordalignment:=ppufile.getbyte;
  3218. vmt_offset:=ppufile.getlongint;
  3219. ppufile.getderef(childofderef);
  3220. ppufile.getsmallset(objectoptions);
  3221. { load guid }
  3222. iidstr:=nil;
  3223. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3224. begin
  3225. new(iidguid);
  3226. ppufile.getguid(iidguid^);
  3227. iidstr:=stringdup(ppufile.getstring);
  3228. end;
  3229. vmtentries:=TFPList.Create;
  3230. vmtentries.count:=ppufile.getlongint;
  3231. for i:=0 to vmtentries.count-1 do
  3232. begin
  3233. ppufile.getderef(d);
  3234. new(vmtentry);
  3235. vmtentry^.procdef:=nil;
  3236. vmtentry^.procdefderef:=d;
  3237. vmtentry^.visibility:=tvisibility(ppufile.getbyte);
  3238. vmtentries[i]:=vmtentry;
  3239. end;
  3240. { load implemented interfaces }
  3241. if objecttype in [odt_class,odt_interfacecorba] then
  3242. begin
  3243. ImplementedInterfaces:=TFPObjectList.Create(true);
  3244. implintfcount:=ppufile.getlongint;
  3245. for i:=0 to implintfcount-1 do
  3246. begin
  3247. ppufile.getderef(d);
  3248. ImplIntf:=TImplementedInterface.Create_deref(d);
  3249. ImplIntf.IOffset:=ppufile.getlongint;
  3250. ImplementedInterfaces.Add(ImplIntf);
  3251. end;
  3252. end
  3253. else
  3254. ImplementedInterfaces:=nil;
  3255. if df_copied_def in defoptions then
  3256. ppufile.getderef(cloneddefderef)
  3257. else
  3258. tObjectSymtable(symtable).ppuload(ppufile);
  3259. { handles the predefined class tobject }
  3260. { the last TOBJECT which is loaded gets }
  3261. { it ! }
  3262. if (childof=nil) and
  3263. (objecttype=odt_class) and
  3264. (objname^='TOBJECT') then
  3265. class_tobject:=self;
  3266. if (childof=nil) and
  3267. (objecttype=odt_interfacecom) and
  3268. (objname^='IUNKNOWN') then
  3269. interface_iunknown:=self;
  3270. writing_class_record_dbginfo:=false;
  3271. end;
  3272. destructor tobjectdef.destroy;
  3273. begin
  3274. if assigned(symtable) then
  3275. begin
  3276. symtable.free;
  3277. symtable:=nil;
  3278. end;
  3279. stringdispose(objname);
  3280. stringdispose(objrealname);
  3281. stringdispose(iidstr);
  3282. if assigned(ImplementedInterfaces) then
  3283. begin
  3284. ImplementedInterfaces.free;
  3285. ImplementedInterfaces:=nil;
  3286. end;
  3287. if assigned(iidguid) then
  3288. begin
  3289. dispose(iidguid);
  3290. iidguid:=nil;
  3291. end;
  3292. if assigned(vmtentries) then
  3293. begin
  3294. resetvmtentries;
  3295. vmtentries.free;
  3296. vmtentries:=nil;
  3297. end;
  3298. if assigned(vmcallstaticinfo) then
  3299. begin
  3300. freemem(vmcallstaticinfo);
  3301. vmcallstaticinfo:=nil;
  3302. end;
  3303. inherited destroy;
  3304. end;
  3305. function tobjectdef.getcopy : tstoreddef;
  3306. var
  3307. i : longint;
  3308. begin
  3309. result:=tobjectdef.create(objecttype,objname^,childof);
  3310. { the constructor allocates a symtable which we release to avoid memory leaks }
  3311. tobjectdef(result).symtable.free;
  3312. tobjectdef(result).symtable:=symtable.getcopy;
  3313. if assigned(objname) then
  3314. tobjectdef(result).objname:=stringdup(objname^);
  3315. if assigned(objrealname) then
  3316. tobjectdef(result).objrealname:=stringdup(objrealname^);
  3317. tobjectdef(result).objectoptions:=objectoptions;
  3318. include(tobjectdef(result).defoptions,df_copied_def);
  3319. tobjectdef(result).vmt_offset:=vmt_offset;
  3320. if assigned(iidguid) then
  3321. begin
  3322. new(tobjectdef(result).iidguid);
  3323. move(iidguid^,tobjectdef(result).iidguid^,sizeof(iidguid^));
  3324. end;
  3325. if assigned(iidstr) then
  3326. tobjectdef(result).iidstr:=stringdup(iidstr^);
  3327. if assigned(ImplementedInterfaces) then
  3328. begin
  3329. for i:=0 to ImplementedInterfaces.count-1 do
  3330. tobjectdef(result).ImplementedInterfaces.Add(TImplementedInterface(ImplementedInterfaces[i]).Getcopy);
  3331. end;
  3332. if assigned(vmtentries) then
  3333. begin
  3334. tobjectdef(result).vmtentries:=TFPList.Create;
  3335. tobjectdef(result).copyvmtentries(self);
  3336. end;
  3337. end;
  3338. procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile);
  3339. var
  3340. i : longint;
  3341. vmtentry : pvmtentry;
  3342. ImplIntf : TImplementedInterface;
  3343. begin
  3344. inherited ppuwrite(ppufile);
  3345. ppufile.putbyte(byte(objecttype));
  3346. ppufile.putstring(objrealname^);
  3347. ppufile.putaint(tObjectSymtable(symtable).datasize);
  3348. ppufile.putbyte(tObjectSymtable(symtable).fieldalignment);
  3349. ppufile.putbyte(tObjectSymtable(symtable).recordalignment);
  3350. ppufile.putlongint(vmt_offset);
  3351. ppufile.putderef(childofderef);
  3352. ppufile.putsmallset(objectoptions);
  3353. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3354. begin
  3355. ppufile.putguid(iidguid^);
  3356. ppufile.putstring(iidstr^);
  3357. end;
  3358. ppufile.putlongint(vmtentries.count);
  3359. for i:=0 to vmtentries.count-1 do
  3360. begin
  3361. vmtentry:=pvmtentry(vmtentries[i]);
  3362. ppufile.putderef(vmtentry^.procdefderef);
  3363. ppufile.putbyte(byte(vmtentry^.visibility));
  3364. end;
  3365. if assigned(ImplementedInterfaces) then
  3366. begin
  3367. ppufile.putlongint(ImplementedInterfaces.Count);
  3368. for i:=0 to ImplementedInterfaces.Count-1 do
  3369. begin
  3370. ImplIntf:=TImplementedInterface(ImplementedInterfaces[i]);
  3371. ppufile.putderef(ImplIntf.intfdefderef);
  3372. ppufile.putlongint(ImplIntf.Ioffset);
  3373. end;
  3374. end;
  3375. if df_copied_def in defoptions then
  3376. ppufile.putderef(cloneddefderef);
  3377. ppufile.writeentry(ibobjectdef);
  3378. if not(df_copied_def in defoptions) then
  3379. tObjectSymtable(symtable).ppuwrite(ppufile);
  3380. end;
  3381. function tobjectdef.GetTypeName:string;
  3382. begin
  3383. { in this case we will go in endless recursion, because then }
  3384. { there is no tsym associated yet with the def. It can occur }
  3385. { (tests/webtbf/tw4757.pp), so for now give a generic name }
  3386. { instead of the actual type name }
  3387. if not assigned(typesym) then
  3388. result:='<Currently Parsed Class>'
  3389. else
  3390. result:=typename;
  3391. end;
  3392. procedure tobjectdef.buildderef;
  3393. var
  3394. i : longint;
  3395. vmtentry : pvmtentry;
  3396. begin
  3397. inherited buildderef;
  3398. childofderef.build(childof);
  3399. if df_copied_def in defoptions then
  3400. cloneddefderef.build(symtable.defowner)
  3401. else
  3402. tstoredsymtable(symtable).buildderef;
  3403. for i:=0 to vmtentries.count-1 do
  3404. begin
  3405. vmtentry:=pvmtentry(vmtentries[i]);
  3406. vmtentry^.procdefderef.build(vmtentry^.procdef);
  3407. end;
  3408. if assigned(ImplementedInterfaces) then
  3409. begin
  3410. for i:=0 to ImplementedInterfaces.count-1 do
  3411. TImplementedInterface(ImplementedInterfaces[i]).buildderef;
  3412. end;
  3413. end;
  3414. procedure tobjectdef.deref;
  3415. var
  3416. i : longint;
  3417. vmtentry : pvmtentry;
  3418. begin
  3419. inherited deref;
  3420. childof:=tobjectdef(childofderef.resolve);
  3421. if df_copied_def in defoptions then
  3422. begin
  3423. cloneddef:=tobjectdef(cloneddefderef.resolve);
  3424. symtable:=cloneddef.symtable.getcopy;
  3425. end
  3426. else
  3427. tstoredsymtable(symtable).deref;
  3428. for i:=0 to vmtentries.count-1 do
  3429. begin
  3430. vmtentry:=pvmtentry(vmtentries[i]);
  3431. vmtentry^.procdef:=tprocdef(vmtentry^.procdefderef.resolve);
  3432. end;
  3433. if assigned(ImplementedInterfaces) then
  3434. begin
  3435. for i:=0 to ImplementedInterfaces.count-1 do
  3436. TImplementedInterface(ImplementedInterfaces[i]).deref;
  3437. end;
  3438. end;
  3439. procedure tobjectdef.buildderefimpl;
  3440. begin
  3441. inherited buildderefimpl;
  3442. if not (df_copied_def in defoptions) then
  3443. tstoredsymtable(symtable).buildderefimpl;
  3444. end;
  3445. procedure tobjectdef.derefimpl;
  3446. begin
  3447. inherited derefimpl;
  3448. if not (df_copied_def in defoptions) then
  3449. tstoredsymtable(symtable).derefimpl;
  3450. end;
  3451. procedure tobjectdef.resetvmtentries;
  3452. var
  3453. i : longint;
  3454. begin
  3455. for i:=0 to vmtentries.Count-1 do
  3456. Dispose(pvmtentry(vmtentries[i]));
  3457. vmtentries.clear;
  3458. end;
  3459. procedure tobjectdef.copyvmtentries(objdef:tobjectdef);
  3460. var
  3461. i : longint;
  3462. vmtentry : pvmtentry;
  3463. begin
  3464. resetvmtentries;
  3465. vmtentries.count:=objdef.vmtentries.count;
  3466. for i:=0 to objdef.vmtentries.count-1 do
  3467. begin
  3468. new(vmtentry);
  3469. vmtentry^:=pvmtentry(objdef.vmtentries[i])^;
  3470. vmtentries[i]:=vmtentry;
  3471. end;
  3472. end;
  3473. function tobjectdef.getparentdef:tdef;
  3474. begin
  3475. { TODO: Remove getparentdef hack}
  3476. { With 2 forward declared classes with the child class before the
  3477. parent class the child class is written earlier to the ppu. Leaving it
  3478. possible to have a reference to the parent class for property overriding,
  3479. but the parent class still has the childof not resolved yet (PFV) }
  3480. if childof=nil then
  3481. childof:=tobjectdef(childofderef.resolve);
  3482. result:=childof;
  3483. end;
  3484. procedure tobjectdef.prepareguid;
  3485. begin
  3486. { set up guid }
  3487. if not assigned(iidguid) then
  3488. begin
  3489. new(iidguid);
  3490. fillchar(iidguid^,sizeof(iidguid^),0); { default null guid }
  3491. end;
  3492. { setup iidstring }
  3493. if not assigned(iidstr) then
  3494. iidstr:=stringdup(''); { default is empty string }
  3495. end;
  3496. procedure tobjectdef.set_parent( c : tobjectdef);
  3497. begin
  3498. if assigned(childof) then
  3499. exit;
  3500. childof:=c;
  3501. if not assigned(c) then
  3502. exit;
  3503. { inherit options and status }
  3504. objectoptions:=objectoptions+(c.objectoptions*inherited_objectoptions);
  3505. { add the data of the anchestor class/object }
  3506. if (objecttype in [odt_class,odt_object,odt_objcclass]) then
  3507. begin
  3508. tObjectSymtable(symtable).datasize:=tObjectSymtable(symtable).datasize+tObjectSymtable(c.symtable).datasize;
  3509. { inherit recordalignment }
  3510. tObjectSymtable(symtable).recordalignment:=tObjectSymtable(c.symtable).recordalignment;
  3511. if (oo_has_vmt in objectoptions) and
  3512. (oo_has_vmt in c.objectoptions) then
  3513. tObjectSymtable(symtable).datasize:=tObjectSymtable(symtable).datasize-sizeof(pint);
  3514. { if parent has a vmt field then the offset is the same for the child PM }
  3515. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  3516. begin
  3517. vmt_offset:=c.vmt_offset;
  3518. include(objectoptions,oo_has_vmt);
  3519. end;
  3520. end;
  3521. end;
  3522. procedure tobjectdef.insertvmt;
  3523. var
  3524. vs: tfieldvarsym;
  3525. begin
  3526. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass] then
  3527. exit;
  3528. if (oo_has_vmt in objectoptions) then
  3529. internalerror(12345)
  3530. else
  3531. begin
  3532. tObjectSymtable(symtable).datasize:=align(tObjectSymtable(symtable).datasize,
  3533. tObjectSymtable(symtable).fieldalignment);
  3534. if (tf_requires_proper_alignment in target_info.flags) then
  3535. begin
  3536. { Align VMT pointer and whole object instance if target CPU requires alignment. }
  3537. tObjectSymtable(symtable).datasize:=align(tObjectSymtable(symtable).datasize,sizeof(pint));
  3538. tObjectSymtable(symtable).alignrecord(tObjectSymtable(symtable).datasize,sizeof(pint));
  3539. end;
  3540. vmt_offset:=tObjectSymtable(symtable).datasize;
  3541. vs:=tfieldvarsym.create('_vptr$'+objname^,vs_value,voidpointertype,[]);
  3542. hidesym(vs);
  3543. tObjectSymtable(symtable).insert(vs);
  3544. tObjectSymtable(symtable).addfield(vs,vis_hidden);
  3545. include(objectoptions,oo_has_vmt);
  3546. end;
  3547. end;
  3548. procedure tobjectdef.check_forwards;
  3549. begin
  3550. if not(objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) then
  3551. tstoredsymtable(symtable).check_forwards;
  3552. if (oo_is_forward in objectoptions) then
  3553. begin
  3554. { ok, in future, the forward can be resolved }
  3555. Message1(sym_e_class_forward_not_resolved,objrealname^);
  3556. exclude(objectoptions,oo_is_forward);
  3557. end;
  3558. end;
  3559. { true, if self inherits from d (or if they are equal) }
  3560. function tobjectdef.is_related(d : tdef) : boolean;
  3561. var
  3562. hp : tobjectdef;
  3563. begin
  3564. hp:=self;
  3565. while assigned(hp) do
  3566. begin
  3567. if hp=d then
  3568. begin
  3569. is_related:=true;
  3570. exit;
  3571. end;
  3572. hp:=hp.childof;
  3573. end;
  3574. is_related:=false;
  3575. end;
  3576. function tobjectdef.FindDestructor : tprocdef;
  3577. var
  3578. objdef : tobjectdef;
  3579. i : longint;
  3580. sym : tsym;
  3581. pd : tprocdef;
  3582. begin
  3583. result:=nil;
  3584. objdef:=self;
  3585. while assigned(objdef) do
  3586. begin
  3587. for i:=0 to objdef.symtable.SymList.Count-1 do
  3588. begin
  3589. sym:=TSym(objdef.symtable.SymList[i]);
  3590. if sym.typ=procsym then
  3591. begin
  3592. pd:=Tprocsym(sym).Find_procdef_bytype(potype_destructor);
  3593. if assigned(pd) then
  3594. begin
  3595. result:=pd;
  3596. exit;
  3597. end;
  3598. end;
  3599. end;
  3600. objdef:=objdef.childof;
  3601. end;
  3602. end;
  3603. function tobjectdef.implements_any_interfaces: boolean;
  3604. begin
  3605. result := (ImplementedInterfaces.Count > 0) or
  3606. (assigned(childof) and childof.implements_any_interfaces);
  3607. end;
  3608. function tobjectdef.size : aint;
  3609. begin
  3610. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass] then
  3611. result:=sizeof(pint)
  3612. else
  3613. result:=tObjectSymtable(symtable).datasize;
  3614. end;
  3615. function tobjectdef.alignment:shortint;
  3616. begin
  3617. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_objcclass] then
  3618. alignment:=sizeof(pint)
  3619. else
  3620. alignment:=tObjectSymtable(symtable).recordalignment;
  3621. end;
  3622. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3623. begin
  3624. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3625. case objecttype of
  3626. odt_class:
  3627. { the +2*sizeof(pint) is size and -size }
  3628. vmtmethodoffset:=(index+10)*sizeof(pint)+2*sizeof(pint);
  3629. odt_objcclass:
  3630. vmtmethodoffset:=0;
  3631. odt_interfacecom,odt_interfacecorba:
  3632. vmtmethodoffset:=index*sizeof(pint);
  3633. else
  3634. {$ifdef WITHDMT}
  3635. vmtmethodoffset:=(index+4)*sizeof(pint);
  3636. {$else WITHDMT}
  3637. vmtmethodoffset:=(index+3)*sizeof(pint);
  3638. {$endif WITHDMT}
  3639. end;
  3640. end;
  3641. function tobjectdef.vmt_mangledname : string;
  3642. begin
  3643. if not(oo_has_vmt in objectoptions) then
  3644. Message1(parser_n_object_has_no_vmt,objrealname^);
  3645. vmt_mangledname:=make_mangledname('VMT',owner,objname^);
  3646. end;
  3647. function tobjectdef.needs_inittable : boolean;
  3648. begin
  3649. case objecttype of
  3650. odt_dispinterface,
  3651. odt_class :
  3652. needs_inittable:=false;
  3653. odt_interfacecom:
  3654. needs_inittable:=true;
  3655. odt_interfacecorba:
  3656. needs_inittable:=is_related(interface_iunknown);
  3657. odt_object:
  3658. needs_inittable:=tObjectSymtable(symtable).needs_init_final;
  3659. odt_cppclass,
  3660. odt_objcclass:
  3661. needs_inittable:=false;
  3662. else
  3663. internalerror(200108267);
  3664. end;
  3665. end;
  3666. function tobjectdef.members_need_inittable : boolean;
  3667. begin
  3668. members_need_inittable:=tObjectSymtable(symtable).needs_init_final;
  3669. end;
  3670. function tobjectdef.find_implemented_interface(aintfdef:tobjectdef):TImplementedInterface;
  3671. var
  3672. ImplIntf : TImplementedInterface;
  3673. i : longint;
  3674. begin
  3675. result:=nil;
  3676. if not assigned(ImplementedInterfaces) then
  3677. exit;
  3678. for i:=0 to ImplementedInterfaces.Count-1 do
  3679. begin
  3680. ImplIntf:=TImplementedInterface(ImplementedInterfaces[i]);
  3681. if ImplIntf.intfdef=aintfdef then
  3682. begin
  3683. result:=ImplIntf;
  3684. exit;
  3685. end;
  3686. end;
  3687. end;
  3688. function tobjectdef.is_publishable : boolean;
  3689. begin
  3690. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface];
  3691. end;
  3692. procedure tobjectdef.reset;
  3693. begin
  3694. inherited reset;
  3695. created_in_current_module:=false;
  3696. maybe_created_in_current_module:=false;
  3697. classref_created_in_current_module:=false;
  3698. end;
  3699. procedure tobjectdef.register_created_classref_type;
  3700. begin
  3701. if not classref_created_in_current_module then
  3702. begin
  3703. classref_created_in_current_module:=true;
  3704. current_module.wpoinfo.addcreatedobjtypeforclassref(self);
  3705. end;
  3706. end;
  3707. procedure tobjectdef.register_created_object_type;
  3708. begin
  3709. if not created_in_current_module then
  3710. begin
  3711. created_in_current_module:=true;
  3712. current_module.wpoinfo.addcreatedobjtype(self);
  3713. end;
  3714. end;
  3715. procedure tobjectdef.register_maybe_created_object_type;
  3716. begin
  3717. { if we know it has been created for sure, no need
  3718. to also record that it maybe can be created in
  3719. this module
  3720. }
  3721. if not (created_in_current_module) and
  3722. not (maybe_created_in_current_module) then
  3723. begin
  3724. maybe_created_in_current_module:=true;
  3725. current_module.wpoinfo.addmaybecreatedbyclassref(self);
  3726. end;
  3727. end;
  3728. procedure tobjectdef.register_vmt_call(index: longint);
  3729. begin
  3730. if (is_object(self) or is_class(self)) then
  3731. current_module.wpoinfo.addcalledvmtentry(self,index);
  3732. end;
  3733. procedure make_procdef_external(data: tobject; arg: pointer);
  3734. var
  3735. def: tdef absolute data;
  3736. begin
  3737. if (def.typ = procdef) then
  3738. begin
  3739. include(tprocdef(def).procoptions,po_external);
  3740. tprocdef(def).forwarddef:=false;
  3741. end;
  3742. end;
  3743. procedure tobjectdef.make_all_methods_external;
  3744. begin
  3745. self.symtable.deflist.foreachcall(@make_procdef_external,nil);
  3746. end;
  3747. {****************************************************************************
  3748. TImplementedInterface
  3749. ****************************************************************************}
  3750. constructor TImplementedInterface.create(aintf: tobjectdef);
  3751. begin
  3752. inherited create;
  3753. intfdef:=aintf;
  3754. IOffset:=-1;
  3755. IType:=etStandard;
  3756. NameMappings:=nil;
  3757. procdefs:=nil;
  3758. end;
  3759. constructor TImplementedInterface.create_deref(d:tderef);
  3760. begin
  3761. inherited create;
  3762. intfdef:=nil;
  3763. intfdefderef:=d;
  3764. IOffset:=-1;
  3765. IType:=etStandard;
  3766. NameMappings:=nil;
  3767. procdefs:=nil;
  3768. end;
  3769. destructor TImplementedInterface.destroy;
  3770. var
  3771. i : longint;
  3772. mappedname : pshortstring;
  3773. begin
  3774. if assigned(NameMappings) then
  3775. begin
  3776. for i:=0 to NameMappings.Count-1 do
  3777. begin
  3778. mappedname:=pshortstring(NameMappings[i]);
  3779. stringdispose(mappedname);
  3780. end;
  3781. NameMappings.free;
  3782. NameMappings:=nil;
  3783. end;
  3784. if assigned(procdefs) then
  3785. begin
  3786. procdefs.free;
  3787. procdefs:=nil;
  3788. end;
  3789. inherited destroy;
  3790. end;
  3791. procedure TImplementedInterface.buildderef;
  3792. begin
  3793. intfdefderef.build(intfdef);
  3794. end;
  3795. procedure TImplementedInterface.deref;
  3796. begin
  3797. intfdef:=tobjectdef(intfdefderef.resolve);
  3798. end;
  3799. procedure TImplementedInterface.AddMapping(const origname,newname: string);
  3800. begin
  3801. if not assigned(NameMappings) then
  3802. NameMappings:=TFPHashList.Create;
  3803. NameMappings.Add(origname,stringdup(newname));
  3804. end;
  3805. function TImplementedInterface.GetMapping(const origname: string):string;
  3806. var
  3807. mappedname : pshortstring;
  3808. begin
  3809. result:='';
  3810. if not assigned(NameMappings) then
  3811. exit;
  3812. mappedname:=PShortstring(NameMappings.Find(origname));
  3813. if assigned(mappedname) then
  3814. result:=mappedname^;
  3815. end;
  3816. procedure TImplementedInterface.AddImplProc(pd:tprocdef);
  3817. begin
  3818. if not assigned(procdefs) then
  3819. procdefs:=TFPObjectList.Create(false);
  3820. { duplicate entries must be stored, because multiple }
  3821. { interfaces can declare methods with the same name }
  3822. { and all of these get their own VMT entry }
  3823. procdefs.Add(pd);
  3824. end;
  3825. function TImplementedInterface.IsImplMergePossible(MergingIntf:TImplementedInterface;out weight: longint): boolean;
  3826. var
  3827. i : longint;
  3828. begin
  3829. result:=false;
  3830. { interfaces being implemented through delegation are not mergable (FK) }
  3831. if (MergingIntf.IType<>etStandard) or not(assigned(ProcDefs)) then
  3832. exit;
  3833. weight:=0;
  3834. { empty interface is mergeable }
  3835. if ProcDefs.Count=0 then
  3836. begin
  3837. result:=true;
  3838. exit;
  3839. end;
  3840. { The interface to merge must at least the number of
  3841. procedures of this interface }
  3842. if MergingIntf.ProcDefs.Count<ProcDefs.Count then
  3843. exit;
  3844. for i:=0 to ProcDefs.Count-1 do
  3845. begin
  3846. if MergingIntf.ProcDefs[i]<>ProcDefs[i] then
  3847. exit;
  3848. end;
  3849. weight:=ProcDefs.Count;
  3850. result:=true;
  3851. end;
  3852. function TImplementedInterface.getcopy:TImplementedInterface;
  3853. begin
  3854. Result:=TImplementedInterface.Create(nil);
  3855. Move(pointer(self)^,pointer(result)^,InstanceSize);
  3856. end;
  3857. {****************************************************************************
  3858. TFORWARDDEF
  3859. ****************************************************************************}
  3860. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  3861. begin
  3862. inherited create(forwarddef);
  3863. tosymname:=stringdup(s);
  3864. forwardpos:=pos;
  3865. end;
  3866. function tforwarddef.GetTypeName:string;
  3867. begin
  3868. GetTypeName:='unresolved forward to '+tosymname^;
  3869. end;
  3870. destructor tforwarddef.destroy;
  3871. begin
  3872. stringdispose(tosymname);
  3873. inherited destroy;
  3874. end;
  3875. {****************************************************************************
  3876. TUNDEFINEDDEF
  3877. ****************************************************************************}
  3878. constructor tundefineddef.create;
  3879. begin
  3880. inherited create(undefineddef);
  3881. end;
  3882. constructor tundefineddef.ppuload(ppufile:tcompilerppufile);
  3883. begin
  3884. inherited ppuload(undefineddef,ppufile);
  3885. end;
  3886. function tundefineddef.GetTypeName:string;
  3887. begin
  3888. GetTypeName:='<undefined type>';
  3889. end;
  3890. procedure tundefineddef.ppuwrite(ppufile:tcompilerppufile);
  3891. begin
  3892. inherited ppuwrite(ppufile);
  3893. ppufile.writeentry(ibundefineddef);
  3894. end;
  3895. {****************************************************************************
  3896. TERRORDEF
  3897. ****************************************************************************}
  3898. constructor terrordef.create;
  3899. begin
  3900. inherited create(errordef);
  3901. { prevent consecutive faults }
  3902. savesize:=1;
  3903. end;
  3904. procedure terrordef.ppuwrite(ppufile:tcompilerppufile);
  3905. begin
  3906. { Can't write errordefs to ppu }
  3907. internalerror(200411063);
  3908. end;
  3909. function terrordef.GetTypeName:string;
  3910. begin
  3911. GetTypeName:='<erroneous type>';
  3912. end;
  3913. function terrordef.getmangledparaname:string;
  3914. begin
  3915. getmangledparaname:='error';
  3916. end;
  3917. {****************************************************************************
  3918. Definition Helpers
  3919. ****************************************************************************}
  3920. function is_interfacecom(def: tdef): boolean;
  3921. begin
  3922. is_interfacecom:=
  3923. assigned(def) and
  3924. (def.typ=objectdef) and
  3925. (tobjectdef(def).objecttype=odt_interfacecom);
  3926. end;
  3927. function is_interfacecorba(def: tdef): boolean;
  3928. begin
  3929. is_interfacecorba:=
  3930. assigned(def) and
  3931. (def.typ=objectdef) and
  3932. (tobjectdef(def).objecttype=odt_interfacecorba);
  3933. end;
  3934. function is_interface(def: tdef): boolean;
  3935. begin
  3936. is_interface:=
  3937. assigned(def) and
  3938. (def.typ=objectdef) and
  3939. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  3940. end;
  3941. function is_dispinterface(def: tdef): boolean;
  3942. begin
  3943. result:=
  3944. assigned(def) and
  3945. (def.typ=objectdef) and
  3946. (tobjectdef(def).objecttype=odt_dispinterface);
  3947. end;
  3948. function is_class(def: tdef): boolean;
  3949. begin
  3950. is_class:=
  3951. assigned(def) and
  3952. (def.typ=objectdef) and
  3953. (tobjectdef(def).objecttype=odt_class);
  3954. end;
  3955. function is_object(def: tdef): boolean;
  3956. begin
  3957. is_object:=
  3958. assigned(def) and
  3959. (def.typ=objectdef) and
  3960. (tobjectdef(def).objecttype=odt_object);
  3961. end;
  3962. function is_cppclass(def: tdef): boolean;
  3963. begin
  3964. is_cppclass:=
  3965. assigned(def) and
  3966. (def.typ=objectdef) and
  3967. (tobjectdef(def).objecttype=odt_cppclass);
  3968. end;
  3969. function is_objcclass(def: tdef): boolean;
  3970. begin
  3971. is_objcclass:=
  3972. assigned(def) and
  3973. (def.typ=objectdef) and
  3974. (tobjectdef(def).objecttype=odt_objcclass);
  3975. end;
  3976. function is_objcclassref(def: tdef): boolean;
  3977. begin
  3978. is_objcclassref:=
  3979. assigned(def) and
  3980. (def.typ=classrefdef) and
  3981. is_objcclass(tclassrefdef(def).pointeddef);
  3982. end;
  3983. function is_class_or_interface(def: tdef): boolean;
  3984. begin
  3985. result:=
  3986. assigned(def) and
  3987. (def.typ=objectdef) and
  3988. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  3989. end;
  3990. function is_class_or_interface_or_object(def: tdef): boolean;
  3991. begin
  3992. result:=
  3993. assigned(def) and
  3994. (def.typ=objectdef) and
  3995. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_object]);
  3996. end;
  3997. function is_class_or_interface_or_dispinterface(def: tdef): boolean;
  3998. begin
  3999. result:=
  4000. assigned(def) and
  4001. (def.typ=objectdef) and
  4002. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface]);
  4003. end;
  4004. procedure loadobjctypes;
  4005. begin
  4006. objc_metaclasstype:=tpointerdef(search_named_unit_globaltype('OBJC1','POBJC_CLASS').typedef);
  4007. objc_superclasstype:=tpointerdef(search_named_unit_globaltype('OBJC1','POBJC_SUPER').typedef);
  4008. objc_idtype:=tpointerdef(search_named_unit_globaltype('OBJC1','ID').typedef);
  4009. objc_seltype:=tpointerdef(search_named_unit_globaltype('OBJC1','SEL').typedef);
  4010. end;
  4011. {$ifdef x86}
  4012. function use_sse(def : tdef) : boolean;
  4013. begin
  4014. use_sse:=(is_single(def) and (current_settings.fputype in sse_singlescalar)) or
  4015. (is_double(def) and (current_settings.fputype in sse_doublescalar));
  4016. end;
  4017. {$endif x86}
  4018. end.