symdef.pas 137 KB

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