symdef.pas 135 KB

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