symdef.pas 172 KB

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