symdef.pas 137 KB

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