symdef.pas 168 KB

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