symdef.pas 172 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543
  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. var
  1047. recsize,recsizep2: longint;
  1048. begin
  1049. is_intregable:=false;
  1050. case deftype of
  1051. orddef,
  1052. pointerdef,
  1053. enumdef,
  1054. classrefdef:
  1055. is_intregable:=true;
  1056. procvardef :
  1057. is_intregable:=not(po_methodpointer in tprocvardef(self).procoptions);
  1058. objectdef:
  1059. is_intregable:=is_class(self) or is_interface(self);
  1060. setdef:
  1061. is_intregable:=(tsetdef(self).settype=smallset);
  1062. recorddef:
  1063. begin
  1064. recsize:=size;
  1065. is_intregable:=
  1066. ispowerof2(recsize,recsizep2) and
  1067. (recsize <= sizeof(aint));
  1068. end;
  1069. end;
  1070. end;
  1071. function tstoreddef.is_fpuregable : boolean;
  1072. begin
  1073. {$ifdef x86}
  1074. result:=use_sse(self);
  1075. {$else x86}
  1076. result:=(deftype=floatdef) and not(cs_fp_emulation in aktmoduleswitches);
  1077. {$endif x86}
  1078. end;
  1079. procedure tstoreddef.initgeneric;
  1080. begin
  1081. if assigned(generictokenbuf) then
  1082. internalerror(200512131);
  1083. generictokenbuf:=tdynamicarray.create(256);
  1084. end;
  1085. {****************************************************************************
  1086. Tstringdef
  1087. ****************************************************************************}
  1088. constructor tstringdef.createshort(l : byte);
  1089. begin
  1090. inherited create(stringdef);
  1091. string_typ:=st_shortstring;
  1092. len:=l;
  1093. savesize:=len+1;
  1094. end;
  1095. constructor tstringdef.loadshort(ppufile:tcompilerppufile);
  1096. begin
  1097. inherited ppuload(stringdef,ppufile);
  1098. string_typ:=st_shortstring;
  1099. len:=ppufile.getbyte;
  1100. savesize:=len+1;
  1101. end;
  1102. constructor tstringdef.createlong(l : aint);
  1103. begin
  1104. inherited create(stringdef);
  1105. string_typ:=st_longstring;
  1106. len:=l;
  1107. savesize:=sizeof(aint);
  1108. end;
  1109. constructor tstringdef.loadlong(ppufile:tcompilerppufile);
  1110. begin
  1111. inherited ppuload(stringdef,ppufile);
  1112. string_typ:=st_longstring;
  1113. len:=ppufile.getaint;
  1114. savesize:=sizeof(aint);
  1115. end;
  1116. constructor tstringdef.createansi(l:aint);
  1117. begin
  1118. inherited create(stringdef);
  1119. string_typ:=st_ansistring;
  1120. len:=l;
  1121. savesize:=sizeof(aint);
  1122. end;
  1123. constructor tstringdef.loadansi(ppufile:tcompilerppufile);
  1124. begin
  1125. inherited ppuload(stringdef,ppufile);
  1126. string_typ:=st_ansistring;
  1127. len:=ppufile.getaint;
  1128. savesize:=sizeof(aint);
  1129. end;
  1130. constructor tstringdef.createwide(l : aint);
  1131. begin
  1132. inherited create(stringdef);
  1133. string_typ:=st_widestring;
  1134. len:=l;
  1135. savesize:=sizeof(aint);
  1136. end;
  1137. constructor tstringdef.loadwide(ppufile:tcompilerppufile);
  1138. begin
  1139. inherited ppuload(stringdef,ppufile);
  1140. string_typ:=st_widestring;
  1141. len:=ppufile.getaint;
  1142. savesize:=sizeof(aint);
  1143. end;
  1144. function tstringdef.getcopy : tstoreddef;
  1145. begin
  1146. result:=tstringdef.create(deftype);
  1147. result.deftype:=stringdef;
  1148. tstringdef(result).string_typ:=string_typ;
  1149. tstringdef(result).len:=len;
  1150. tstringdef(result).savesize:=savesize;
  1151. end;
  1152. function tstringdef.stringtypname:string;
  1153. const
  1154. typname:array[tstringtype] of string[8]=(
  1155. 'shortstr','longstr','ansistr','widestr'
  1156. );
  1157. begin
  1158. stringtypname:=typname[string_typ];
  1159. end;
  1160. procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
  1161. begin
  1162. inherited ppuwrite(ppufile);
  1163. if string_typ=st_shortstring then
  1164. begin
  1165. {$ifdef extdebug}
  1166. if len > 255 then internalerror(12122002);
  1167. {$endif}
  1168. ppufile.putbyte(byte(len))
  1169. end
  1170. else
  1171. ppufile.putaint(len);
  1172. case string_typ of
  1173. st_shortstring : ppufile.writeentry(ibshortstringdef);
  1174. st_longstring : ppufile.writeentry(iblongstringdef);
  1175. st_ansistring : ppufile.writeentry(ibansistringdef);
  1176. st_widestring : ppufile.writeentry(ibwidestringdef);
  1177. end;
  1178. end;
  1179. function tstringdef.needs_inittable : boolean;
  1180. begin
  1181. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  1182. end;
  1183. function tstringdef.gettypename : string;
  1184. const
  1185. names : array[tstringtype] of string[11] = (
  1186. 'ShortString','LongString','AnsiString','WideString');
  1187. begin
  1188. gettypename:=names[string_typ];
  1189. end;
  1190. function tstringdef.alignment : shortint;
  1191. begin
  1192. case string_typ of
  1193. st_widestring,
  1194. st_ansistring:
  1195. alignment:=size_2_align(savesize);
  1196. st_longstring,
  1197. st_shortstring:
  1198. {$ifdef cpurequiresproperalignment}
  1199. { char to string accesses byte 0 and 1 with one word access }
  1200. alignment:=size_2_align(2);
  1201. {$else cpurequiresproperalignment}
  1202. alignment:=size_2_align(1);
  1203. {$endif cpurequiresproperalignment}
  1204. else
  1205. internalerror(200412301);
  1206. end;
  1207. end;
  1208. procedure tstringdef.write_rtti_data(rt:trttitype);
  1209. begin
  1210. case string_typ of
  1211. st_ansistring:
  1212. begin
  1213. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkAString));
  1214. write_rtti_name;
  1215. end;
  1216. st_widestring:
  1217. begin
  1218. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkWString));
  1219. write_rtti_name;
  1220. end;
  1221. st_longstring:
  1222. begin
  1223. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkLString));
  1224. write_rtti_name;
  1225. end;
  1226. st_shortstring:
  1227. begin
  1228. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkSString));
  1229. write_rtti_name;
  1230. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(len));
  1231. {$ifdef cpurequiresproperalignment}
  1232. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1233. {$endif cpurequiresproperalignment}
  1234. end;
  1235. end;
  1236. end;
  1237. function tstringdef.getmangledparaname : string;
  1238. begin
  1239. getmangledparaname:='STRING';
  1240. end;
  1241. function tstringdef.is_publishable : boolean;
  1242. begin
  1243. is_publishable:=true;
  1244. end;
  1245. {****************************************************************************
  1246. TENUMDEF
  1247. ****************************************************************************}
  1248. constructor tenumdef.create;
  1249. begin
  1250. inherited create(enumdef);
  1251. minval:=0;
  1252. maxval:=0;
  1253. calcsavesize;
  1254. has_jumps:=false;
  1255. basedef:=nil;
  1256. firstenum:=nil;
  1257. end;
  1258. constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:aint);
  1259. begin
  1260. inherited create(enumdef);
  1261. minval:=_min;
  1262. maxval:=_max;
  1263. basedef:=_basedef;
  1264. calcsavesize;
  1265. has_jumps:=false;
  1266. firstenum:=basedef.firstenum;
  1267. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1268. firstenum:=tenumsym(firstenum).nextenum;
  1269. end;
  1270. constructor tenumdef.ppuload(ppufile:tcompilerppufile);
  1271. begin
  1272. inherited ppuload(enumdef,ppufile);
  1273. ppufile.getderef(basedefderef);
  1274. minval:=ppufile.getaint;
  1275. maxval:=ppufile.getaint;
  1276. savesize:=ppufile.getaint;
  1277. has_jumps:=false;
  1278. firstenum:=Nil;
  1279. end;
  1280. function tenumdef.getcopy : tstoreddef;
  1281. begin
  1282. if assigned(basedef) then
  1283. result:=tenumdef.create_subrange(basedef,minval,maxval)
  1284. else
  1285. begin
  1286. result:=tenumdef.create;
  1287. tenumdef(result).minval:=minval;
  1288. tenumdef(result).maxval:=maxval;
  1289. end;
  1290. tenumdef(result).has_jumps:=has_jumps;
  1291. tenumdef(result).firstenum:=firstenum;
  1292. tenumdef(result).basedefderef:=basedefderef;
  1293. end;
  1294. procedure tenumdef.calcsavesize;
  1295. begin
  1296. if (aktpackenum=8) or (min<low(longint)) or (int64(max)>high(cardinal)) then
  1297. savesize:=8
  1298. else
  1299. if (aktpackenum=4) or (min<low(smallint)) or (max>high(word)) then
  1300. savesize:=4
  1301. else
  1302. if (aktpackenum=2) or (min<low(shortint)) or (max>high(byte)) then
  1303. savesize:=2
  1304. else
  1305. savesize:=1;
  1306. end;
  1307. procedure tenumdef.setmax(_max:aint);
  1308. begin
  1309. maxval:=_max;
  1310. calcsavesize;
  1311. end;
  1312. procedure tenumdef.setmin(_min:aint);
  1313. begin
  1314. minval:=_min;
  1315. calcsavesize;
  1316. end;
  1317. function tenumdef.min:aint;
  1318. begin
  1319. min:=minval;
  1320. end;
  1321. function tenumdef.max:aint;
  1322. begin
  1323. max:=maxval;
  1324. end;
  1325. procedure tenumdef.buildderef;
  1326. begin
  1327. inherited buildderef;
  1328. basedefderef.build(basedef);
  1329. end;
  1330. procedure tenumdef.deref;
  1331. begin
  1332. inherited deref;
  1333. basedef:=tenumdef(basedefderef.resolve);
  1334. { restart ordering }
  1335. firstenum:=nil;
  1336. end;
  1337. procedure tenumdef.derefimpl;
  1338. begin
  1339. if assigned(basedef) and
  1340. (firstenum=nil) then
  1341. begin
  1342. firstenum:=basedef.firstenum;
  1343. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1344. firstenum:=tenumsym(firstenum).nextenum;
  1345. end;
  1346. end;
  1347. destructor tenumdef.destroy;
  1348. begin
  1349. inherited destroy;
  1350. end;
  1351. procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
  1352. begin
  1353. inherited ppuwrite(ppufile);
  1354. ppufile.putderef(basedefderef);
  1355. ppufile.putaint(min);
  1356. ppufile.putaint(max);
  1357. ppufile.putaint(savesize);
  1358. ppufile.writeentry(ibenumdef);
  1359. end;
  1360. procedure tenumdef.write_child_rtti_data(rt:trttitype);
  1361. begin
  1362. if assigned(basedef) then
  1363. basedef.get_rtti_label(rt);
  1364. end;
  1365. procedure tenumdef.write_rtti_data(rt:trttitype);
  1366. var
  1367. hp : tenumsym;
  1368. begin
  1369. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkEnumeration));
  1370. write_rtti_name;
  1371. {$ifdef cpurequiresproperalignment}
  1372. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1373. {$endif cpurequiresproperalignment}
  1374. case longint(savesize) of
  1375. 1:
  1376. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUByte));
  1377. 2:
  1378. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otUWord));
  1379. 4:
  1380. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  1381. end;
  1382. {$ifdef cpurequiresproperalignment}
  1383. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(4));
  1384. {$endif cpurequiresproperalignment}
  1385. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(min));
  1386. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(max));
  1387. if assigned(basedef) then
  1388. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(basedef.get_rtti_label(rt)))
  1389. else
  1390. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  1391. hp:=tenumsym(firstenum);
  1392. while assigned(hp) do
  1393. begin
  1394. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(hp.realname)));
  1395. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(hp.realname));
  1396. hp:=hp.nextenum;
  1397. end;
  1398. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  1399. end;
  1400. function tenumdef.is_publishable : boolean;
  1401. begin
  1402. is_publishable:=true;
  1403. end;
  1404. function tenumdef.gettypename : string;
  1405. begin
  1406. gettypename:='<enumeration type>';
  1407. end;
  1408. {****************************************************************************
  1409. TORDDEF
  1410. ****************************************************************************}
  1411. constructor torddef.create(t : tbasetype;v,b : TConstExprInt);
  1412. begin
  1413. inherited create(orddef);
  1414. low:=v;
  1415. high:=b;
  1416. typ:=t;
  1417. setsize;
  1418. end;
  1419. constructor torddef.ppuload(ppufile:tcompilerppufile);
  1420. begin
  1421. inherited ppuload(orddef,ppufile);
  1422. typ:=tbasetype(ppufile.getbyte);
  1423. if sizeof(TConstExprInt)=8 then
  1424. begin
  1425. low:=ppufile.getint64;
  1426. high:=ppufile.getint64;
  1427. end
  1428. else
  1429. begin
  1430. low:=ppufile.getlongint;
  1431. high:=ppufile.getlongint;
  1432. end;
  1433. setsize;
  1434. end;
  1435. function torddef.getcopy : tstoreddef;
  1436. begin
  1437. result:=torddef.create(typ,low,high);
  1438. result.deftype:=orddef;
  1439. torddef(result).low:=low;
  1440. torddef(result).high:=high;
  1441. torddef(result).typ:=typ;
  1442. torddef(result).savesize:=savesize;
  1443. end;
  1444. function torddef.alignment:shortint;
  1445. begin
  1446. if (target_info.system = system_i386_darwin) and
  1447. (typ in [s64bit,u64bit]) then
  1448. result := 4
  1449. else
  1450. result := inherited alignment;
  1451. end;
  1452. procedure torddef.setsize;
  1453. const
  1454. sizetbl : array[tbasetype] of longint = (
  1455. 0,
  1456. 1,2,4,8,
  1457. 1,2,4,8,
  1458. 1,2,4,
  1459. 1,2,8
  1460. );
  1461. begin
  1462. savesize:=sizetbl[typ];
  1463. end;
  1464. function torddef.getvartype : longint;
  1465. const
  1466. basetype2vartype : array[tbasetype] of longint = (
  1467. varUndefined,
  1468. varbyte,varqword,varlongword,varqword,
  1469. varshortint,varsmallint,varinteger,varint64,
  1470. varboolean,varUndefined,varUndefined,
  1471. varUndefined,varUndefined,varCurrency);
  1472. begin
  1473. result:=basetype2vartype[typ];
  1474. end;
  1475. procedure torddef.ppuwrite(ppufile:tcompilerppufile);
  1476. begin
  1477. inherited ppuwrite(ppufile);
  1478. ppufile.putbyte(byte(typ));
  1479. if sizeof(TConstExprInt)=8 then
  1480. begin
  1481. ppufile.putint64(low);
  1482. ppufile.putint64(high);
  1483. end
  1484. else
  1485. begin
  1486. ppufile.putlongint(low);
  1487. ppufile.putlongint(high);
  1488. end;
  1489. ppufile.writeentry(iborddef);
  1490. end;
  1491. procedure torddef.write_rtti_data(rt:trttitype);
  1492. procedure dointeger;
  1493. const
  1494. trans : array[tbasetype] of byte =
  1495. (otUByte{otNone},
  1496. otUByte,otUWord,otULong,otUByte{otNone},
  1497. otSByte,otSWord,otSLong,otUByte{otNone},
  1498. otUByte,otUWord,otULong,
  1499. otUByte,otUWord,otUByte);
  1500. begin
  1501. write_rtti_name;
  1502. {$ifdef cpurequiresproperalignment}
  1503. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1504. {$endif cpurequiresproperalignment}
  1505. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(byte(trans[typ])));
  1506. {$ifdef cpurequiresproperalignment}
  1507. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(4));
  1508. {$endif cpurequiresproperalignment}
  1509. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(low)));
  1510. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(high)));
  1511. end;
  1512. begin
  1513. case typ of
  1514. s64bit :
  1515. begin
  1516. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInt64));
  1517. write_rtti_name;
  1518. {$ifdef cpurequiresproperalignment}
  1519. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1520. {$endif cpurequiresproperalignment}
  1521. { low }
  1522. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(int64($80000000) shl 32));
  1523. { high }
  1524. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit((int64($7fffffff) shl 32) or int64($ffffffff)));
  1525. end;
  1526. u64bit :
  1527. begin
  1528. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkQWord));
  1529. write_rtti_name;
  1530. {$ifdef cpurequiresproperalignment}
  1531. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1532. {$endif cpurequiresproperalignment}
  1533. { low }
  1534. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(0));
  1535. { high }
  1536. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_64bit(int64((int64($ffffffff) shl 32) or int64($ffffffff))));
  1537. end;
  1538. bool8bit:
  1539. begin
  1540. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkBool));
  1541. dointeger;
  1542. end;
  1543. uchar:
  1544. begin
  1545. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkChar));
  1546. dointeger;
  1547. end;
  1548. uwidechar:
  1549. begin
  1550. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkWChar));
  1551. dointeger;
  1552. end;
  1553. else
  1554. begin
  1555. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkInteger));
  1556. dointeger;
  1557. end;
  1558. end;
  1559. end;
  1560. function torddef.is_publishable : boolean;
  1561. begin
  1562. is_publishable:=(typ<>uvoid);
  1563. end;
  1564. function torddef.gettypename : string;
  1565. const
  1566. names : array[tbasetype] of string[20] = (
  1567. 'untyped',
  1568. 'Byte','Word','DWord','QWord',
  1569. 'ShortInt','SmallInt','LongInt','Int64',
  1570. 'Boolean','WordBool','LongBool',
  1571. 'Char','WideChar','Currency');
  1572. begin
  1573. gettypename:=names[typ];
  1574. end;
  1575. {****************************************************************************
  1576. TFLOATDEF
  1577. ****************************************************************************}
  1578. constructor tfloatdef.create(t : tfloattype);
  1579. begin
  1580. inherited create(floatdef);
  1581. typ:=t;
  1582. setsize;
  1583. end;
  1584. constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
  1585. begin
  1586. inherited ppuload(floatdef,ppufile);
  1587. typ:=tfloattype(ppufile.getbyte);
  1588. setsize;
  1589. end;
  1590. function tfloatdef.getcopy : tstoreddef;
  1591. begin
  1592. result:=tfloatdef.create(typ);
  1593. result.deftype:=floatdef;
  1594. tfloatdef(result).savesize:=savesize;
  1595. end;
  1596. function tfloatdef.alignment:shortint;
  1597. begin
  1598. if (target_info.system = system_i386_darwin) then
  1599. case typ of
  1600. s80real : result:=16;
  1601. s64real,
  1602. s64currency,
  1603. s64comp : result:=4;
  1604. else
  1605. result := inherited alignment;
  1606. end
  1607. else
  1608. result := inherited alignment;
  1609. end;
  1610. procedure tfloatdef.setsize;
  1611. begin
  1612. case typ of
  1613. s32real : savesize:=4;
  1614. s80real : savesize:=10;
  1615. s64real,
  1616. s64currency,
  1617. s64comp : savesize:=8;
  1618. else
  1619. savesize:=0;
  1620. end;
  1621. end;
  1622. function tfloatdef.getvartype : longint;
  1623. const
  1624. floattype2vartype : array[tfloattype] of longint = (
  1625. varSingle,varDouble,varUndefined,
  1626. varUndefined,varCurrency,varUndefined);
  1627. begin
  1628. if (upper(typename)='TDATETIME') and
  1629. assigned(owner) and
  1630. assigned(owner.name) and
  1631. (owner.name^='SYSTEM') then
  1632. result:=varDate
  1633. else
  1634. result:=floattype2vartype[typ];
  1635. end;
  1636. procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
  1637. begin
  1638. inherited ppuwrite(ppufile);
  1639. ppufile.putbyte(byte(typ));
  1640. ppufile.writeentry(ibfloatdef);
  1641. end;
  1642. procedure tfloatdef.write_rtti_data(rt:trttitype);
  1643. const
  1644. {tfloattype = (s32real,s64real,s80real,s64bit,s128bit);}
  1645. translate : array[tfloattype] of byte =
  1646. (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,ftFloat128);
  1647. begin
  1648. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkFloat));
  1649. write_rtti_name;
  1650. {$ifdef cpurequiresproperalignment}
  1651. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  1652. {$endif cpurequiresproperalignment}
  1653. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(translate[typ]));
  1654. end;
  1655. function tfloatdef.is_publishable : boolean;
  1656. begin
  1657. is_publishable:=true;
  1658. end;
  1659. function tfloatdef.gettypename : string;
  1660. const
  1661. names : array[tfloattype] of string[20] = (
  1662. 'Single','Double','Extended','Comp','Currency','Float128');
  1663. begin
  1664. gettypename:=names[typ];
  1665. end;
  1666. {****************************************************************************
  1667. TFILEDEF
  1668. ****************************************************************************}
  1669. constructor tfiledef.createtext;
  1670. begin
  1671. inherited create(filedef);
  1672. filetyp:=ft_text;
  1673. typedfiletype.reset;
  1674. setsize;
  1675. end;
  1676. constructor tfiledef.createuntyped;
  1677. begin
  1678. inherited create(filedef);
  1679. filetyp:=ft_untyped;
  1680. typedfiletype.reset;
  1681. setsize;
  1682. end;
  1683. constructor tfiledef.createtyped(const tt : ttype);
  1684. begin
  1685. inherited create(filedef);
  1686. filetyp:=ft_typed;
  1687. typedfiletype:=tt;
  1688. setsize;
  1689. end;
  1690. constructor tfiledef.ppuload(ppufile:tcompilerppufile);
  1691. begin
  1692. inherited ppuload(filedef,ppufile);
  1693. filetyp:=tfiletyp(ppufile.getbyte);
  1694. if filetyp=ft_typed then
  1695. ppufile.gettype(typedfiletype)
  1696. else
  1697. typedfiletype.reset;
  1698. setsize;
  1699. end;
  1700. function tfiledef.getcopy : tstoreddef;
  1701. begin
  1702. case filetyp of
  1703. ft_typed:
  1704. result:=tfiledef.createtyped(typedfiletype);
  1705. ft_untyped:
  1706. result:=tfiledef.createuntyped;
  1707. ft_text:
  1708. result:=tfiledef.createtext;
  1709. else
  1710. internalerror(2004121201);
  1711. end;
  1712. end;
  1713. procedure tfiledef.buildderef;
  1714. begin
  1715. inherited buildderef;
  1716. if filetyp=ft_typed then
  1717. typedfiletype.buildderef;
  1718. end;
  1719. procedure tfiledef.deref;
  1720. begin
  1721. inherited deref;
  1722. if filetyp=ft_typed then
  1723. typedfiletype.resolve;
  1724. end;
  1725. procedure tfiledef.setsize;
  1726. begin
  1727. {$ifdef cpu64bit}
  1728. case filetyp of
  1729. ft_text :
  1730. if target_info.system in [system_x86_64_win64,system_ia64_win64] then
  1731. savesize:=632
  1732. else
  1733. savesize:=628;
  1734. ft_typed,
  1735. ft_untyped :
  1736. if target_info.system in [system_x86_64_win64,system_ia64_win64] then
  1737. savesize:=372
  1738. else
  1739. savesize:=368;
  1740. end;
  1741. {$else cpu64bit}
  1742. case filetyp of
  1743. ft_text :
  1744. savesize:=592;
  1745. ft_typed,
  1746. ft_untyped :
  1747. savesize:=332;
  1748. end;
  1749. {$endif cpu64bit}
  1750. end;
  1751. procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
  1752. begin
  1753. inherited ppuwrite(ppufile);
  1754. ppufile.putbyte(byte(filetyp));
  1755. if filetyp=ft_typed then
  1756. ppufile.puttype(typedfiletype);
  1757. ppufile.writeentry(ibfiledef);
  1758. end;
  1759. function tfiledef.gettypename : string;
  1760. begin
  1761. case filetyp of
  1762. ft_untyped:
  1763. gettypename:='File';
  1764. ft_typed:
  1765. gettypename:='File Of '+typedfiletype.def.typename;
  1766. ft_text:
  1767. gettypename:='Text'
  1768. end;
  1769. end;
  1770. function tfiledef.getmangledparaname : string;
  1771. begin
  1772. case filetyp of
  1773. ft_untyped:
  1774. getmangledparaname:='FILE';
  1775. ft_typed:
  1776. getmangledparaname:='FILE$OF$'+typedfiletype.def.mangledparaname;
  1777. ft_text:
  1778. getmangledparaname:='TEXT'
  1779. end;
  1780. end;
  1781. {****************************************************************************
  1782. TVARIANTDEF
  1783. ****************************************************************************}
  1784. constructor tvariantdef.create(v : tvarianttype);
  1785. begin
  1786. inherited create(variantdef);
  1787. varianttype:=v;
  1788. setsize;
  1789. end;
  1790. constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
  1791. begin
  1792. inherited ppuload(variantdef,ppufile);
  1793. varianttype:=tvarianttype(ppufile.getbyte);
  1794. setsize;
  1795. end;
  1796. function tvariantdef.getcopy : tstoreddef;
  1797. begin
  1798. result:=tvariantdef.create(varianttype);
  1799. end;
  1800. procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
  1801. begin
  1802. inherited ppuwrite(ppufile);
  1803. ppufile.putbyte(byte(varianttype));
  1804. ppufile.writeentry(ibvariantdef);
  1805. end;
  1806. procedure tvariantdef.setsize;
  1807. begin
  1808. {$ifdef cpu64bit}
  1809. savesize:=24;
  1810. {$else cpu64bit}
  1811. savesize:=16;
  1812. {$endif cpu64bit}
  1813. end;
  1814. function tvariantdef.gettypename : string;
  1815. begin
  1816. case varianttype of
  1817. vt_normalvariant:
  1818. gettypename:='Variant';
  1819. vt_olevariant:
  1820. gettypename:='OleVariant';
  1821. end;
  1822. end;
  1823. procedure tvariantdef.write_rtti_data(rt:trttitype);
  1824. begin
  1825. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkVariant));
  1826. end;
  1827. function tvariantdef.needs_inittable : boolean;
  1828. begin
  1829. needs_inittable:=true;
  1830. end;
  1831. function tvariantdef.is_publishable : boolean;
  1832. begin
  1833. is_publishable:=true;
  1834. end;
  1835. {****************************************************************************
  1836. TABSTRACTPOINTERDEF
  1837. ****************************************************************************}
  1838. constructor tabstractpointerdef.create(dt:tdeftype;const tt : ttype);
  1839. begin
  1840. inherited create(dt);
  1841. pointertype:=tt;
  1842. savesize:=sizeof(aint);
  1843. end;
  1844. constructor tabstractpointerdef.ppuload(dt:tdeftype;ppufile:tcompilerppufile);
  1845. begin
  1846. inherited ppuload(dt,ppufile);
  1847. ppufile.gettype(pointertype);
  1848. savesize:=sizeof(aint);
  1849. end;
  1850. procedure tabstractpointerdef.buildderef;
  1851. begin
  1852. inherited buildderef;
  1853. pointertype.buildderef;
  1854. end;
  1855. procedure tabstractpointerdef.deref;
  1856. begin
  1857. inherited deref;
  1858. pointertype.resolve;
  1859. end;
  1860. procedure tabstractpointerdef.ppuwrite(ppufile:tcompilerppufile);
  1861. begin
  1862. inherited ppuwrite(ppufile);
  1863. ppufile.puttype(pointertype);
  1864. end;
  1865. {****************************************************************************
  1866. TPOINTERDEF
  1867. ****************************************************************************}
  1868. constructor tpointerdef.create(const tt : ttype);
  1869. begin
  1870. inherited create(pointerdef,tt);
  1871. is_far:=false;
  1872. end;
  1873. constructor tpointerdef.createfar(const tt : ttype);
  1874. begin
  1875. inherited create(pointerdef,tt);
  1876. is_far:=true;
  1877. end;
  1878. constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
  1879. begin
  1880. inherited ppuload(pointerdef,ppufile);
  1881. is_far:=(ppufile.getbyte<>0);
  1882. end;
  1883. function tpointerdef.getcopy : tstoreddef;
  1884. begin
  1885. result:=tpointerdef.create(pointertype);
  1886. tpointerdef(result).is_far:=is_far;
  1887. tpointerdef(result).savesize:=savesize;
  1888. end;
  1889. procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
  1890. begin
  1891. inherited ppuwrite(ppufile);
  1892. ppufile.putbyte(byte(is_far));
  1893. ppufile.writeentry(ibpointerdef);
  1894. end;
  1895. function tpointerdef.gettypename : string;
  1896. begin
  1897. if is_far then
  1898. gettypename:='^'+pointertype.def.typename+';far'
  1899. else
  1900. gettypename:='^'+pointertype.def.typename;
  1901. end;
  1902. {****************************************************************************
  1903. TCLASSREFDEF
  1904. ****************************************************************************}
  1905. constructor tclassrefdef.create(const t:ttype);
  1906. begin
  1907. inherited create(classrefdef,t);
  1908. end;
  1909. constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
  1910. begin
  1911. inherited ppuload(classrefdef,ppufile);
  1912. end;
  1913. procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
  1914. begin
  1915. inherited ppuwrite(ppufile);
  1916. ppufile.writeentry(ibclassrefdef);
  1917. end;
  1918. function tclassrefdef.gettypename : string;
  1919. begin
  1920. gettypename:='Class Of '+pointertype.def.typename;
  1921. end;
  1922. function tclassrefdef.is_publishable : boolean;
  1923. begin
  1924. result:=true;
  1925. end;
  1926. {***************************************************************************
  1927. TSETDEF
  1928. ***************************************************************************}
  1929. constructor tsetdef.create(const t:ttype;high : aint);
  1930. begin
  1931. inherited create(setdef);
  1932. elementtype:=t;
  1933. // setbase:=low;
  1934. setmax:=high;
  1935. if high<32 then
  1936. begin
  1937. settype:=smallset;
  1938. {$ifdef testvarsets}
  1939. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  1940. {$endif}
  1941. savesize:=Sizeof(longint)
  1942. {$ifdef testvarsets}
  1943. else {No, use $PACKSET VALUE for rounding}
  1944. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  1945. {$endif}
  1946. ;
  1947. end
  1948. else
  1949. if high<256 then
  1950. begin
  1951. settype:=normset;
  1952. savesize:=32;
  1953. end
  1954. else
  1955. {$ifdef testvarsets}
  1956. if high<$10000 then
  1957. begin
  1958. settype:=varset;
  1959. savesize:=4*((high+31) div 32);
  1960. end
  1961. else
  1962. {$endif testvarsets}
  1963. Message(sym_e_ill_type_decl_set);
  1964. end;
  1965. constructor tsetdef.ppuload(ppufile:tcompilerppufile);
  1966. begin
  1967. inherited ppuload(setdef,ppufile);
  1968. ppufile.gettype(elementtype);
  1969. settype:=tsettype(ppufile.getbyte);
  1970. case settype of
  1971. normset : savesize:=32;
  1972. varset : savesize:=ppufile.getlongint;
  1973. smallset : savesize:=Sizeof(longint);
  1974. end;
  1975. end;
  1976. destructor tsetdef.destroy;
  1977. begin
  1978. inherited destroy;
  1979. end;
  1980. function tsetdef.getcopy : tstoreddef;
  1981. begin
  1982. case settype of
  1983. smallset:
  1984. result:=tsetdef.create(elementtype,31);
  1985. normset:
  1986. result:=tsetdef.create(elementtype,255);
  1987. else
  1988. internalerror(2004121202);
  1989. end;
  1990. end;
  1991. procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
  1992. begin
  1993. inherited ppuwrite(ppufile);
  1994. ppufile.puttype(elementtype);
  1995. ppufile.putbyte(byte(settype));
  1996. if settype=varset then
  1997. ppufile.putlongint(savesize);
  1998. if settype=normset then
  1999. ppufile.putaint(savesize);
  2000. ppufile.writeentry(ibsetdef);
  2001. end;
  2002. procedure tsetdef.buildderef;
  2003. begin
  2004. inherited buildderef;
  2005. elementtype.buildderef;
  2006. end;
  2007. procedure tsetdef.deref;
  2008. begin
  2009. inherited deref;
  2010. elementtype.resolve;
  2011. end;
  2012. procedure tsetdef.write_child_rtti_data(rt:trttitype);
  2013. begin
  2014. tstoreddef(elementtype.def).get_rtti_label(rt);
  2015. end;
  2016. procedure tsetdef.write_rtti_data(rt:trttitype);
  2017. begin
  2018. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkSet));
  2019. write_rtti_name;
  2020. {$ifdef cpurequiresproperalignment}
  2021. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  2022. {$endif cpurequiresproperalignment}
  2023. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(otULong));
  2024. {$ifdef cpurequiresproperalignment}
  2025. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  2026. {$endif cpurequiresproperalignment}
  2027. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2028. end;
  2029. function tsetdef.is_publishable : boolean;
  2030. begin
  2031. is_publishable:=(settype=smallset);
  2032. end;
  2033. function tsetdef.gettypename : string;
  2034. begin
  2035. if assigned(elementtype.def) then
  2036. gettypename:='Set Of '+elementtype.def.typename
  2037. else
  2038. gettypename:='Empty Set';
  2039. end;
  2040. {***************************************************************************
  2041. TFORMALDEF
  2042. ***************************************************************************}
  2043. constructor tformaldef.create;
  2044. begin
  2045. inherited create(formaldef);
  2046. savesize:=0;
  2047. end;
  2048. constructor tformaldef.ppuload(ppufile:tcompilerppufile);
  2049. begin
  2050. inherited ppuload(formaldef,ppufile);
  2051. savesize:=0;
  2052. end;
  2053. procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
  2054. begin
  2055. inherited ppuwrite(ppufile);
  2056. ppufile.writeentry(ibformaldef);
  2057. end;
  2058. function tformaldef.gettypename : string;
  2059. begin
  2060. gettypename:='<Formal type>';
  2061. end;
  2062. {***************************************************************************
  2063. TARRAYDEF
  2064. ***************************************************************************}
  2065. constructor tarraydef.create(l,h : aint;const t : ttype);
  2066. begin
  2067. inherited create(arraydef);
  2068. lowrange:=l;
  2069. highrange:=h;
  2070. rangetype:=t;
  2071. elementtype.reset;
  2072. arrayoptions:=[];
  2073. end;
  2074. constructor tarraydef.create_from_pointer(const elemt : ttype);
  2075. begin
  2076. self.create(0,$7fffffff,s32inttype);
  2077. arrayoptions:=[ado_IsConvertedPointer];
  2078. setelementtype(elemt);
  2079. end;
  2080. constructor tarraydef.ppuload(ppufile:tcompilerppufile);
  2081. begin
  2082. inherited ppuload(arraydef,ppufile);
  2083. { the addresses are calculated later }
  2084. ppufile.gettype(_elementtype);
  2085. ppufile.gettype(rangetype);
  2086. lowrange:=ppufile.getaint;
  2087. highrange:=ppufile.getaint;
  2088. ppufile.getsmallset(arrayoptions);
  2089. end;
  2090. function tarraydef.getcopy : tstoreddef;
  2091. begin
  2092. result:=tarraydef.create(lowrange,highrange,rangetype);
  2093. tarraydef(result).arrayoptions:=arrayoptions;
  2094. tarraydef(result)._elementtype:=_elementtype;
  2095. end;
  2096. procedure tarraydef.buildderef;
  2097. begin
  2098. inherited buildderef;
  2099. _elementtype.buildderef;
  2100. rangetype.buildderef;
  2101. end;
  2102. procedure tarraydef.deref;
  2103. begin
  2104. inherited deref;
  2105. _elementtype.resolve;
  2106. rangetype.resolve;
  2107. end;
  2108. procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
  2109. begin
  2110. inherited ppuwrite(ppufile);
  2111. ppufile.puttype(_elementtype);
  2112. ppufile.puttype(rangetype);
  2113. ppufile.putaint(lowrange);
  2114. ppufile.putaint(highrange);
  2115. ppufile.putsmallset(arrayoptions);
  2116. ppufile.writeentry(ibarraydef);
  2117. end;
  2118. function tarraydef.elesize : aint;
  2119. begin
  2120. elesize:=_elementtype.def.size;
  2121. end;
  2122. function tarraydef.elecount : aint;
  2123. var
  2124. qhigh,qlow : qword;
  2125. begin
  2126. if ado_IsDynamicArray in arrayoptions then
  2127. begin
  2128. result:=0;
  2129. exit;
  2130. end;
  2131. if (highrange>0) and (lowrange<0) then
  2132. begin
  2133. qhigh:=highrange;
  2134. qlow:=qword(-lowrange);
  2135. { prevent overflow, return -1 to indicate overflow }
  2136. if qhigh+qlow>qword(high(aint)-1) then
  2137. result:=-1
  2138. else
  2139. result:=qhigh+qlow+1;
  2140. end
  2141. else
  2142. result:=int64(highrange)-lowrange+1;
  2143. end;
  2144. function tarraydef.size : aint;
  2145. var
  2146. cachedelecount,
  2147. cachedelesize : aint;
  2148. begin
  2149. if ado_IsDynamicArray in arrayoptions then
  2150. begin
  2151. size:=sizeof(aint);
  2152. exit;
  2153. end;
  2154. { Tarraydef.size may never be called for an open array! }
  2155. if highrange<lowrange then
  2156. internalerror(99080501);
  2157. cachedelesize:=elesize;
  2158. cachedelecount:=elecount;
  2159. { prevent overflow, return -1 to indicate overflow }
  2160. if (cachedelesize <> 0) and
  2161. (
  2162. (cachedelecount < 0) or
  2163. ((high(aint) div cachedelesize) < cachedelecount) or
  2164. { also lowrange*elesize must be < high(aint) to prevent overflow when
  2165. accessing the array, see ncgmem (PFV) }
  2166. ((high(aint) div cachedelesize) < abs(lowrange))
  2167. ) then
  2168. result:=-1
  2169. else
  2170. result:=cachedelesize*cachedelecount;
  2171. end;
  2172. procedure tarraydef.setelementtype(t: ttype);
  2173. begin
  2174. _elementtype:=t;
  2175. if not((ado_IsDynamicArray in arrayoptions) or
  2176. (ado_IsConvertedPointer in arrayoptions) or
  2177. (highrange<lowrange)) then
  2178. begin
  2179. if (size=-1) then
  2180. Message(sym_e_segment_too_large);
  2181. end;
  2182. end;
  2183. function tarraydef.alignment : shortint;
  2184. begin
  2185. { alignment is the size of the elements }
  2186. if (elementtype.def.deftype in [arraydef,recorddef]) or
  2187. ((elementtype.def.deftype=objectdef) and
  2188. is_object(elementtype.def)) then
  2189. alignment:=elementtype.def.alignment
  2190. else
  2191. alignment:=size_2_align(elesize);
  2192. end;
  2193. function tarraydef.needs_inittable : boolean;
  2194. begin
  2195. needs_inittable:=(ado_IsDynamicArray in arrayoptions) or elementtype.def.needs_inittable;
  2196. end;
  2197. procedure tarraydef.write_child_rtti_data(rt:trttitype);
  2198. begin
  2199. tstoreddef(elementtype.def).get_rtti_label(rt);
  2200. end;
  2201. procedure tarraydef.write_rtti_data(rt:trttitype);
  2202. begin
  2203. if ado_IsDynamicArray in arrayoptions then
  2204. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkdynarray))
  2205. else
  2206. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkarray));
  2207. write_rtti_name;
  2208. {$ifdef cpurequiresproperalignment}
  2209. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  2210. {$endif cpurequiresproperalignment}
  2211. { size of elements }
  2212. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_aint(elesize));
  2213. if not(ado_IsDynamicArray in arrayoptions) then
  2214. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_aint(elecount));
  2215. { element type }
  2216. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2217. { variant type }
  2218. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tstoreddef(elementtype.def).getvartype));
  2219. end;
  2220. function tarraydef.gettypename : string;
  2221. begin
  2222. if (ado_IsConstString in arrayoptions) then
  2223. result:='Constant String'
  2224. else if (ado_isarrayofconst in arrayoptions) or
  2225. (ado_isConstructor in arrayoptions) then
  2226. begin
  2227. if (ado_isvariant in arrayoptions) or ((highrange=-1) and (lowrange=0)) then
  2228. gettypename:='Array Of Const'
  2229. else
  2230. gettypename:='Array Of '+elementtype.def.typename;
  2231. end
  2232. else if ((highrange=-1) and (lowrange=0)) or (ado_IsDynamicArray in arrayoptions) then
  2233. gettypename:='Array Of '+elementtype.def.typename
  2234. else
  2235. begin
  2236. if rangetype.def.deftype=enumdef then
  2237. gettypename:='Array['+rangetype.def.typename+'] Of '+elementtype.def.typename
  2238. else
  2239. gettypename:='Array['+tostr(lowrange)+'..'+
  2240. tostr(highrange)+'] Of '+elementtype.def.typename
  2241. end;
  2242. end;
  2243. function tarraydef.getmangledparaname : string;
  2244. begin
  2245. if ado_isarrayofconst in arrayoptions then
  2246. getmangledparaname:='array_of_const'
  2247. else
  2248. if ((highrange=-1) and (lowrange=0)) then
  2249. getmangledparaname:='array_of_'+elementtype.def.mangledparaname
  2250. else
  2251. internalerror(200204176);
  2252. end;
  2253. {***************************************************************************
  2254. tabstractrecorddef
  2255. ***************************************************************************}
  2256. function tabstractrecorddef.getsymtable(t:tgetsymtable):tsymtable;
  2257. begin
  2258. if t=gs_record then
  2259. getsymtable:=symtable
  2260. else
  2261. getsymtable:=nil;
  2262. end;
  2263. procedure tabstractrecorddef.reset;
  2264. begin
  2265. inherited reset;
  2266. tstoredsymtable(symtable).reset_all_defs;
  2267. end;
  2268. procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem;arg:pointer);
  2269. begin
  2270. if (FRTTIType=fullrtti) or
  2271. ((tsym(sym).typ=fieldvarsym) and
  2272. tfieldvarsym(sym).vartype.def.needs_inittable) then
  2273. inc(Count);
  2274. end;
  2275. procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem;arg:pointer);
  2276. begin
  2277. if (FRTTIType=fullrtti) or
  2278. ((tsym(sym).typ=fieldvarsym) and
  2279. tfieldvarsym(sym).vartype.def.needs_inittable) then
  2280. tstoreddef(tfieldvarsym(sym).vartype.def).get_rtti_label(FRTTIType);
  2281. end;
  2282. procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem;arg:pointer);
  2283. begin
  2284. if (FRTTIType=fullrtti) or
  2285. ((tsym(sym).typ=fieldvarsym) and
  2286. tfieldvarsym(sym).vartype.def.needs_inittable) then
  2287. begin
  2288. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(tstoreddef(tfieldvarsym(sym).vartype.def).get_rtti_label(FRTTIType)));
  2289. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tfieldvarsym(sym).fieldoffset));
  2290. end;
  2291. end;
  2292. procedure tabstractrecorddef.buildderefimpl;
  2293. begin
  2294. inherited buildderefimpl;
  2295. tstoredsymtable(symtable).buildderefimpl;
  2296. end;
  2297. procedure tabstractrecorddef.derefimpl;
  2298. var
  2299. storesymtable : tsymtable;
  2300. begin
  2301. inherited derefimpl;
  2302. tstoredsymtable(symtable).derefimpl;
  2303. end;
  2304. {***************************************************************************
  2305. trecorddef
  2306. ***************************************************************************}
  2307. constructor trecorddef.create(p : tsymtable);
  2308. begin
  2309. inherited create(recorddef);
  2310. symtable:=p;
  2311. symtable.defowner:=self;
  2312. isunion:=false;
  2313. end;
  2314. constructor trecorddef.ppuload(ppufile:tcompilerppufile);
  2315. begin
  2316. inherited ppuload(recorddef,ppufile);
  2317. symtable:=trecordsymtable.create(0);
  2318. trecordsymtable(symtable).datasize:=ppufile.getaint;
  2319. trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
  2320. trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
  2321. trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
  2322. trecordsymtable(symtable).ppuload(ppufile);
  2323. symtable.defowner:=self;
  2324. isunion:=false;
  2325. end;
  2326. destructor trecorddef.destroy;
  2327. begin
  2328. if assigned(symtable) then
  2329. symtable.free;
  2330. inherited destroy;
  2331. end;
  2332. function trecorddef.getcopy : tstoreddef;
  2333. begin
  2334. result:=trecorddef.create(symtable.getcopy);
  2335. trecorddef(result).isunion:=isunion;
  2336. end;
  2337. function trecorddef.needs_inittable : boolean;
  2338. begin
  2339. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2340. end;
  2341. procedure trecorddef.buildderef;
  2342. var
  2343. oldrecsyms : tsymtable;
  2344. begin
  2345. inherited buildderef;
  2346. oldrecsyms:=aktrecordsymtable;
  2347. aktrecordsymtable:=symtable;
  2348. { now build the definitions }
  2349. tstoredsymtable(symtable).buildderef;
  2350. aktrecordsymtable:=oldrecsyms;
  2351. end;
  2352. procedure trecorddef.deref;
  2353. var
  2354. oldrecsyms : tsymtable;
  2355. begin
  2356. inherited deref;
  2357. oldrecsyms:=aktrecordsymtable;
  2358. aktrecordsymtable:=symtable;
  2359. { now dereference the definitions }
  2360. tstoredsymtable(symtable).deref;
  2361. aktrecordsymtable:=oldrecsyms;
  2362. { assign TGUID? load only from system unit }
  2363. if not(assigned(rec_tguid)) and
  2364. (upper(typename)='TGUID') and
  2365. assigned(owner) and
  2366. assigned(owner.name) and
  2367. (owner.name^='SYSTEM') then
  2368. rec_tguid:=self;
  2369. end;
  2370. procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
  2371. begin
  2372. inherited ppuwrite(ppufile);
  2373. ppufile.putaint(trecordsymtable(symtable).datasize);
  2374. ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
  2375. ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
  2376. ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
  2377. ppufile.writeentry(ibrecorddef);
  2378. trecordsymtable(symtable).ppuwrite(ppufile);
  2379. end;
  2380. function trecorddef.size:aint;
  2381. begin
  2382. result:=trecordsymtable(symtable).datasize;
  2383. end;
  2384. function trecorddef.alignment:shortint;
  2385. begin
  2386. alignment:=trecordsymtable(symtable).recordalignment;
  2387. end;
  2388. function trecorddef.padalignment:shortint;
  2389. begin
  2390. padalignment := trecordsymtable(symtable).padalignment;
  2391. end;
  2392. procedure trecorddef.write_child_rtti_data(rt:trttitype);
  2393. begin
  2394. FRTTIType:=rt;
  2395. symtable.foreach(@generate_field_rtti,nil);
  2396. end;
  2397. procedure trecorddef.write_rtti_data(rt:trttitype);
  2398. begin
  2399. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkrecord));
  2400. write_rtti_name;
  2401. {$ifdef cpurequiresproperalignment}
  2402. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  2403. {$endif cpurequiresproperalignment}
  2404. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(size));
  2405. Count:=0;
  2406. FRTTIType:=rt;
  2407. symtable.foreach(@count_field_rtti,nil);
  2408. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(Count));
  2409. symtable.foreach(@write_field_rtti,nil);
  2410. end;
  2411. function trecorddef.gettypename : string;
  2412. begin
  2413. gettypename:='<record type>'
  2414. end;
  2415. {***************************************************************************
  2416. TABSTRACTPROCDEF
  2417. ***************************************************************************}
  2418. constructor tabstractprocdef.create(dt:tdeftype;level:byte);
  2419. begin
  2420. inherited create(dt);
  2421. parast:=tparasymtable.create(level);
  2422. parast.defowner:=self;
  2423. paras:=nil;
  2424. minparacount:=0;
  2425. maxparacount:=0;
  2426. proctypeoption:=potype_none;
  2427. proccalloption:=pocall_none;
  2428. procoptions:=[];
  2429. rettype:=voidtype;
  2430. {$ifdef i386}
  2431. fpu_used:=0;
  2432. {$endif i386}
  2433. savesize:=sizeof(aint);
  2434. requiredargarea:=0;
  2435. has_paraloc_info:=false;
  2436. location_reset(funcretloc[callerside],LOC_INVALID,OS_NO);
  2437. location_reset(funcretloc[calleeside],LOC_INVALID,OS_NO);
  2438. end;
  2439. destructor tabstractprocdef.destroy;
  2440. begin
  2441. if assigned(paras) then
  2442. begin
  2443. {$ifdef MEMDEBUG}
  2444. memprocpara.start;
  2445. {$endif MEMDEBUG}
  2446. paras.free;
  2447. {$ifdef MEMDEBUG}
  2448. memprocpara.stop;
  2449. {$endif MEMDEBUG}
  2450. end;
  2451. if assigned(parast) then
  2452. begin
  2453. {$ifdef MEMDEBUG}
  2454. memprocparast.start;
  2455. {$endif MEMDEBUG}
  2456. parast.free;
  2457. {$ifdef MEMDEBUG}
  2458. memprocparast.stop;
  2459. {$endif MEMDEBUG}
  2460. end;
  2461. inherited destroy;
  2462. end;
  2463. procedure tabstractprocdef.releasemem;
  2464. begin
  2465. if assigned(paras) then
  2466. begin
  2467. paras.free;
  2468. paras:=nil;
  2469. end;
  2470. parast.free;
  2471. parast:=nil;
  2472. end;
  2473. procedure tabstractprocdef.count_para(p:tnamedindexitem;arg:pointer);
  2474. begin
  2475. if (tsym(p).typ<>paravarsym) then
  2476. exit;
  2477. inc(plongint(arg)^);
  2478. if not(vo_is_hidden_para in tparavarsym(p).varoptions) then
  2479. begin
  2480. if not assigned(tparavarsym(p).defaultconstsym) then
  2481. inc(minparacount);
  2482. inc(maxparacount);
  2483. end;
  2484. end;
  2485. procedure tabstractprocdef.insert_para(p:tnamedindexitem;arg:pointer);
  2486. begin
  2487. if (tsym(p).typ<>paravarsym) then
  2488. exit;
  2489. paras.add(p);
  2490. end;
  2491. procedure tabstractprocdef.calcparas;
  2492. var
  2493. paracount : longint;
  2494. begin
  2495. { This can already be assigned when
  2496. we need to reresolve this unit (PFV) }
  2497. if assigned(paras) then
  2498. paras.free;
  2499. paras:=tparalist.create(false);
  2500. paracount:=0;
  2501. minparacount:=0;
  2502. maxparacount:=0;
  2503. parast.foreach(@count_para,@paracount);
  2504. paras.capacity:=paracount;
  2505. { Insert parameters in table }
  2506. parast.foreach(@insert_para,nil);
  2507. { Order parameters }
  2508. paras.sortparas;
  2509. end;
  2510. { all functions returning in FPU are
  2511. assume to use 2 FPU registers
  2512. until the function implementation
  2513. is processed PM }
  2514. procedure tabstractprocdef.test_if_fpu_result;
  2515. begin
  2516. {$ifdef i386}
  2517. if assigned(rettype.def) and
  2518. (rettype.def.deftype=floatdef) then
  2519. fpu_used:=maxfpuregs;
  2520. {$endif i386}
  2521. end;
  2522. procedure tabstractprocdef.buildderef;
  2523. begin
  2524. { released procdef? }
  2525. if not assigned(parast) then
  2526. exit;
  2527. inherited buildderef;
  2528. rettype.buildderef;
  2529. { parast }
  2530. tparasymtable(parast).buildderef;
  2531. end;
  2532. procedure tabstractprocdef.deref;
  2533. begin
  2534. inherited deref;
  2535. rettype.resolve;
  2536. { parast }
  2537. tparasymtable(parast).deref;
  2538. { recalculated parameters }
  2539. calcparas;
  2540. end;
  2541. constructor tabstractprocdef.ppuload(dt:tdeftype;ppufile:tcompilerppufile);
  2542. var
  2543. b : byte;
  2544. begin
  2545. inherited ppuload(dt,ppufile);
  2546. parast:=nil;
  2547. Paras:=nil;
  2548. minparacount:=0;
  2549. maxparacount:=0;
  2550. ppufile.gettype(rettype);
  2551. {$ifdef i386}
  2552. fpu_used:=ppufile.getbyte;
  2553. {$else}
  2554. ppufile.getbyte;
  2555. {$endif i386}
  2556. proctypeoption:=tproctypeoption(ppufile.getbyte);
  2557. proccalloption:=tproccalloption(ppufile.getbyte);
  2558. ppufile.getnormalset(procoptions);
  2559. location_reset(funcretloc[callerside],LOC_INVALID,OS_NO);
  2560. location_reset(funcretloc[calleeside],LOC_INVALID,OS_NO);
  2561. if po_explicitparaloc in procoptions then
  2562. begin
  2563. b:=ppufile.getbyte;
  2564. if b<>sizeof(funcretloc[callerside]) then
  2565. internalerror(200411154);
  2566. ppufile.getdata(funcretloc[callerside],sizeof(funcretloc[callerside]));
  2567. end;
  2568. savesize:=sizeof(aint);
  2569. has_paraloc_info:=(po_explicitparaloc in procoptions);
  2570. end;
  2571. procedure tabstractprocdef.ppuwrite(ppufile:tcompilerppufile);
  2572. var
  2573. oldintfcrc : boolean;
  2574. begin
  2575. { released procdef? }
  2576. if not assigned(parast) then
  2577. exit;
  2578. inherited ppuwrite(ppufile);
  2579. ppufile.puttype(rettype);
  2580. oldintfcrc:=ppufile.do_interface_crc;
  2581. ppufile.do_interface_crc:=false;
  2582. {$ifdef i386}
  2583. if simplify_ppu then
  2584. fpu_used:=0;
  2585. ppufile.putbyte(fpu_used);
  2586. {$else}
  2587. ppufile.putbyte(0);
  2588. {$endif}
  2589. ppufile.putbyte(ord(proctypeoption));
  2590. ppufile.putbyte(ord(proccalloption));
  2591. ppufile.putnormalset(procoptions);
  2592. ppufile.do_interface_crc:=oldintfcrc;
  2593. if (po_explicitparaloc in procoptions) then
  2594. begin
  2595. { Make a 'valid' funcretloc for procedures }
  2596. ppufile.putbyte(sizeof(funcretloc[callerside]));
  2597. ppufile.putdata(funcretloc[callerside],sizeof(funcretloc[callerside]));
  2598. end;
  2599. end;
  2600. function tabstractprocdef.typename_paras(showhidden:boolean) : string;
  2601. var
  2602. hs,s : string;
  2603. hp : TParavarsym;
  2604. hpc : tconstsym;
  2605. first : boolean;
  2606. i : integer;
  2607. begin
  2608. s:='';
  2609. first:=true;
  2610. for i:=0 to paras.count-1 do
  2611. begin
  2612. hp:=tparavarsym(paras[i]);
  2613. if not(vo_is_hidden_para in hp.varoptions) or
  2614. (showhidden) then
  2615. begin
  2616. if first then
  2617. begin
  2618. s:=s+'(';
  2619. first:=false;
  2620. end
  2621. else
  2622. s:=s+',';
  2623. case hp.varspez of
  2624. vs_var :
  2625. s:=s+'var';
  2626. vs_const :
  2627. s:=s+'const';
  2628. vs_out :
  2629. s:=s+'out';
  2630. end;
  2631. if assigned(hp.vartype.def.typesym) then
  2632. begin
  2633. if s<>'(' then
  2634. s:=s+' ';
  2635. hs:=hp.vartype.def.typesym.realname;
  2636. if hs[1]<>'$' then
  2637. s:=s+hp.vartype.def.typesym.realname
  2638. else
  2639. s:=s+hp.vartype.def.gettypename;
  2640. end
  2641. else
  2642. s:=s+hp.vartype.def.gettypename;
  2643. { default value }
  2644. if assigned(hp.defaultconstsym) then
  2645. begin
  2646. hpc:=tconstsym(hp.defaultconstsym);
  2647. hs:='';
  2648. case hpc.consttyp of
  2649. conststring,
  2650. constresourcestring :
  2651. hs:=strpas(pchar(hpc.value.valueptr));
  2652. constreal :
  2653. str(pbestreal(hpc.value.valueptr)^,hs);
  2654. constpointer :
  2655. hs:=tostr(hpc.value.valueordptr);
  2656. constord :
  2657. begin
  2658. if is_boolean(hpc.consttype.def) then
  2659. begin
  2660. if hpc.value.valueord<>0 then
  2661. hs:='TRUE'
  2662. else
  2663. hs:='FALSE';
  2664. end
  2665. else
  2666. hs:=tostr(hpc.value.valueord);
  2667. end;
  2668. constnil :
  2669. hs:='nil';
  2670. constset :
  2671. hs:='<set>';
  2672. end;
  2673. if hs<>'' then
  2674. s:=s+'="'+hs+'"';
  2675. end;
  2676. end;
  2677. end;
  2678. if not first then
  2679. s:=s+')';
  2680. if (po_varargs in procoptions) then
  2681. s:=s+';VarArgs';
  2682. typename_paras:=s;
  2683. end;
  2684. function tabstractprocdef.is_methodpointer:boolean;
  2685. begin
  2686. result:=false;
  2687. end;
  2688. function tabstractprocdef.is_addressonly:boolean;
  2689. begin
  2690. result:=true;
  2691. end;
  2692. {***************************************************************************
  2693. TPROCDEF
  2694. ***************************************************************************}
  2695. constructor tprocdef.create(level:byte);
  2696. begin
  2697. inherited create(procdef,level);
  2698. _mangledname:=nil;
  2699. fileinfo:=aktfilepos;
  2700. extnumber:=$ffff;
  2701. aliasnames:=tstringlist.create;
  2702. funcretsym:=nil;
  2703. localst := nil;
  2704. defref:=nil;
  2705. lastwritten:=nil;
  2706. refcount:=0;
  2707. if (cs_browser in aktmoduleswitches) and make_ref then
  2708. begin
  2709. defref:=tref.create(defref,@akttokenpos);
  2710. inc(refcount);
  2711. end;
  2712. lastref:=defref;
  2713. forwarddef:=true;
  2714. interfacedef:=false;
  2715. hasforward:=false;
  2716. _class := nil;
  2717. import_dll:=nil;
  2718. import_name:=nil;
  2719. import_nr:=0;
  2720. inlininginfo:=nil;
  2721. end;
  2722. constructor tprocdef.ppuload(ppufile:tcompilerppufile);
  2723. var
  2724. level : byte;
  2725. begin
  2726. inherited ppuload(procdef,ppufile);
  2727. if po_has_mangledname in procoptions then
  2728. _mangledname:=stringdup(ppufile.getstring)
  2729. else
  2730. _mangledname:=nil;
  2731. extnumber:=ppufile.getword;
  2732. level:=ppufile.getbyte;
  2733. ppufile.getderef(_classderef);
  2734. ppufile.getderef(procsymderef);
  2735. ppufile.getposinfo(fileinfo);
  2736. ppufile.getsmallset(symoptions);
  2737. {$ifdef powerpc}
  2738. { library symbol for AmigaOS/MorphOS }
  2739. ppufile.getderef(libsymderef);
  2740. {$endif powerpc}
  2741. { import stuff }
  2742. if po_has_importdll in procoptions then
  2743. import_dll:=stringdup(ppufile.getstring)
  2744. else
  2745. import_dll:=nil;
  2746. if po_has_importname in procoptions then
  2747. import_name:=stringdup(ppufile.getstring)
  2748. else
  2749. import_name:=nil;
  2750. import_nr:=ppufile.getword;
  2751. { inline stuff }
  2752. if (po_has_inlininginfo in procoptions) then
  2753. begin
  2754. ppufile.getderef(funcretsymderef);
  2755. new(inlininginfo);
  2756. ppufile.getsmallset(inlininginfo^.flags);
  2757. end
  2758. else
  2759. begin
  2760. inlininginfo:=nil;
  2761. funcretsym:=nil;
  2762. end;
  2763. { load para symtable }
  2764. parast:=tparasymtable.create(level);
  2765. tparasymtable(parast).ppuload(ppufile);
  2766. parast.defowner:=self;
  2767. { load local symtable }
  2768. if (po_has_inlininginfo in procoptions) or
  2769. ((current_module.flags and uf_local_browser)<>0) then
  2770. begin
  2771. localst:=tlocalsymtable.create(level);
  2772. tlocalsymtable(localst).ppuload(ppufile);
  2773. localst.defowner:=self;
  2774. end
  2775. else
  2776. localst:=nil;
  2777. { inline stuff }
  2778. if (po_has_inlininginfo in procoptions) then
  2779. inlininginfo^.code:=ppuloadnodetree(ppufile);
  2780. { default values for no persistent data }
  2781. if (cs_link_deffile in aktglobalswitches) and
  2782. (tf_need_export in target_info.flags) and
  2783. (po_exports in procoptions) then
  2784. deffile.AddExport(mangledname);
  2785. aliasnames:=tstringlist.create;
  2786. forwarddef:=false;
  2787. interfacedef:=false;
  2788. hasforward:=false;
  2789. lastref:=nil;
  2790. lastwritten:=nil;
  2791. defref:=nil;
  2792. refcount:=0;
  2793. { Disable po_has_inlining until the derefimpl is done }
  2794. exclude(procoptions,po_has_inlininginfo);
  2795. end;
  2796. destructor tprocdef.destroy;
  2797. begin
  2798. if assigned(defref) then
  2799. begin
  2800. defref.freechain;
  2801. defref.free;
  2802. end;
  2803. aliasnames.free;
  2804. if assigned(localst) and (localst.symtabletype<>staticsymtable) then
  2805. begin
  2806. {$ifdef MEMDEBUG}
  2807. memproclocalst.start;
  2808. {$endif MEMDEBUG}
  2809. localst.free;
  2810. {$ifdef MEMDEBUG}
  2811. memproclocalst.start;
  2812. {$endif MEMDEBUG}
  2813. end;
  2814. if assigned(inlininginfo) then
  2815. begin
  2816. {$ifdef MEMDEBUG}
  2817. memprocnodetree.start;
  2818. {$endif MEMDEBUG}
  2819. tnode(inlininginfo^.code).free;
  2820. {$ifdef MEMDEBUG}
  2821. memprocnodetree.start;
  2822. {$endif MEMDEBUG}
  2823. dispose(inlininginfo);
  2824. end;
  2825. stringdispose(import_dll);
  2826. stringdispose(import_name);
  2827. if (po_msgstr in procoptions) then
  2828. strdispose(messageinf.str);
  2829. if assigned(_mangledname) then
  2830. begin
  2831. {$ifdef MEMDEBUG}
  2832. memmanglednames.start;
  2833. {$endif MEMDEBUG}
  2834. stringdispose(_mangledname);
  2835. {$ifdef MEMDEBUG}
  2836. memmanglednames.stop;
  2837. {$endif MEMDEBUG}
  2838. end;
  2839. inherited destroy;
  2840. end;
  2841. procedure tprocdef.ppuwrite(ppufile:tcompilerppufile);
  2842. var
  2843. oldintfcrc : boolean;
  2844. oldparasymtable,
  2845. oldlocalsymtable : tsymtable;
  2846. begin
  2847. { released procdef? }
  2848. if not assigned(parast) then
  2849. exit;
  2850. oldparasymtable:=aktparasymtable;
  2851. oldlocalsymtable:=aktlocalsymtable;
  2852. aktparasymtable:=parast;
  2853. aktlocalsymtable:=localst;
  2854. inherited ppuwrite(ppufile);
  2855. oldintfcrc:=ppufile.do_interface_crc;
  2856. ppufile.do_interface_crc:=false;
  2857. ppufile.do_interface_crc:=oldintfcrc;
  2858. if po_has_mangledname in procoptions then
  2859. ppufile.putstring(_mangledname^);
  2860. ppufile.putword(extnumber);
  2861. ppufile.putbyte(parast.symtablelevel);
  2862. ppufile.putderef(_classderef);
  2863. ppufile.putderef(procsymderef);
  2864. ppufile.putposinfo(fileinfo);
  2865. ppufile.putsmallset(symoptions);
  2866. {$ifdef powerpc}
  2867. { library symbol for AmigaOS/MorphOS }
  2868. ppufile.putderef(libsymderef);
  2869. {$endif powerpc}
  2870. { import }
  2871. if po_has_importdll in procoptions then
  2872. ppufile.putstring(import_dll^);
  2873. if po_has_importname in procoptions then
  2874. ppufile.putstring(import_name^);
  2875. ppufile.putword(import_nr);
  2876. { inline stuff }
  2877. oldintfcrc:=ppufile.do_crc;
  2878. ppufile.do_crc:=false;
  2879. if (po_has_inlininginfo in procoptions) then
  2880. begin
  2881. ppufile.putderef(funcretsymderef);
  2882. ppufile.putsmallset(inlininginfo^.flags);
  2883. end;
  2884. ppufile.do_crc:=oldintfcrc;
  2885. { write this entry }
  2886. ppufile.writeentry(ibprocdef);
  2887. { Save the para symtable, this is taken from the interface }
  2888. tparasymtable(parast).ppuwrite(ppufile);
  2889. { save localsymtable for inline procedures or when local
  2890. browser info is requested, this has no influence on the crc }
  2891. if (po_has_inlininginfo in procoptions) or
  2892. ((current_module.flags and uf_local_browser)<>0) then
  2893. begin
  2894. { we must write a localsymtable }
  2895. if not assigned(localst) then
  2896. insert_localst;
  2897. oldintfcrc:=ppufile.do_crc;
  2898. ppufile.do_crc:=false;
  2899. tlocalsymtable(localst).ppuwrite(ppufile);
  2900. ppufile.do_crc:=oldintfcrc;
  2901. end;
  2902. { node tree for inlining }
  2903. oldintfcrc:=ppufile.do_crc;
  2904. ppufile.do_crc:=false;
  2905. if (po_has_inlininginfo in procoptions) then
  2906. ppuwritenodetree(ppufile,inlininginfo^.code);
  2907. ppufile.do_crc:=oldintfcrc;
  2908. aktparasymtable:=oldparasymtable;
  2909. aktlocalsymtable:=oldlocalsymtable;
  2910. end;
  2911. procedure tprocdef.reset;
  2912. begin
  2913. inherited reset;
  2914. procstarttai:=nil;
  2915. procendtai:=nil;
  2916. end;
  2917. procedure tprocdef.insert_localst;
  2918. begin
  2919. localst:=tlocalsymtable.create(parast.symtablelevel);
  2920. localst.defowner:=self;
  2921. end;
  2922. function tprocdef.fullprocname(showhidden:boolean):string;
  2923. var
  2924. s : string;
  2925. t : ttoken;
  2926. begin
  2927. {$ifdef EXTDEBUG}
  2928. showhidden:=true;
  2929. {$endif EXTDEBUG}
  2930. s:='';
  2931. if owner.symtabletype=localsymtable then
  2932. s:=s+'local ';
  2933. if assigned(_class) then
  2934. begin
  2935. if po_classmethod in procoptions then
  2936. s:=s+'class ';
  2937. s:=s+_class.objrealname^+'.';
  2938. end;
  2939. if proctypeoption=potype_operator then
  2940. begin
  2941. for t:=NOTOKEN to last_overloaded do
  2942. if procsym.realname='$'+overloaded_names[t] then
  2943. begin
  2944. s:='operator '+arraytokeninfo[t].str+typename_paras(showhidden);
  2945. break;
  2946. end;
  2947. end
  2948. else
  2949. s:=s+procsym.realname+typename_paras(showhidden);
  2950. case proctypeoption of
  2951. potype_constructor:
  2952. s:='constructor '+s;
  2953. potype_destructor:
  2954. s:='destructor '+s;
  2955. else
  2956. if assigned(rettype.def) and
  2957. not(is_void(rettype.def)) then
  2958. s:=s+':'+rettype.def.gettypename;
  2959. end;
  2960. { forced calling convention? }
  2961. if (po_hascallingconvention in procoptions) then
  2962. s:=s+';'+ProcCallOptionStr[proccalloption];
  2963. fullprocname:=s;
  2964. end;
  2965. function tprocdef.is_methodpointer:boolean;
  2966. begin
  2967. result:=assigned(_class);
  2968. end;
  2969. function tprocdef.is_addressonly:boolean;
  2970. begin
  2971. result:=assigned(owner) and
  2972. (owner.symtabletype<>objectsymtable);
  2973. end;
  2974. function tprocdef.is_visible_for_object(currobjdef:tobjectdef):boolean;
  2975. begin
  2976. is_visible_for_object:=false;
  2977. { private symbols are allowed when we are in the same
  2978. module as they are defined }
  2979. if (sp_private in symoptions) and
  2980. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  2981. not(owner.defowner.owner.iscurrentunit) then
  2982. exit;
  2983. if (sp_strictprivate in symoptions) then
  2984. begin
  2985. result:=currobjdef=tobjectdef(owner.defowner);
  2986. exit;
  2987. end;
  2988. if (sp_strictprotected in symoptions) then
  2989. begin
  2990. result:=assigned(currobjdef) and
  2991. currobjdef.is_related(tobjectdef(owner.defowner));
  2992. exit;
  2993. end;
  2994. { protected symbols are visible in the module that defines them and
  2995. also visible to related objects. The related object must be defined
  2996. in the current module }
  2997. if (sp_protected in symoptions) and
  2998. (
  2999. (
  3000. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3001. not(owner.defowner.owner.iscurrentunit)
  3002. ) and
  3003. not(
  3004. assigned(currobjdef) and
  3005. (currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3006. (currobjdef.owner.iscurrentunit) and
  3007. currobjdef.is_related(tobjectdef(owner.defowner))
  3008. )
  3009. ) then
  3010. exit;
  3011. is_visible_for_object:=true;
  3012. end;
  3013. function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
  3014. begin
  3015. case t of
  3016. gs_local :
  3017. getsymtable:=localst;
  3018. gs_para :
  3019. getsymtable:=parast;
  3020. else
  3021. getsymtable:=nil;
  3022. end;
  3023. end;
  3024. procedure tprocdef.load_references(ppufile:tcompilerppufile;locals:boolean);
  3025. var
  3026. pos : tfileposinfo;
  3027. move_last : boolean;
  3028. oldparasymtable,
  3029. oldlocalsymtable : tsymtable;
  3030. begin
  3031. oldparasymtable:=aktparasymtable;
  3032. oldlocalsymtable:=aktlocalsymtable;
  3033. aktparasymtable:=parast;
  3034. aktlocalsymtable:=localst;
  3035. move_last:=lastwritten=lastref;
  3036. while (not ppufile.endofentry) do
  3037. begin
  3038. ppufile.getposinfo(pos);
  3039. inc(refcount);
  3040. lastref:=tref.create(lastref,@pos);
  3041. lastref.is_written:=true;
  3042. if refcount=1 then
  3043. defref:=lastref;
  3044. end;
  3045. if move_last then
  3046. lastwritten:=lastref;
  3047. if ((current_module.flags and uf_local_browser)<>0) and
  3048. assigned(localst) and
  3049. locals then
  3050. begin
  3051. tparasymtable(parast).load_references(ppufile,locals);
  3052. tlocalsymtable(localst).load_references(ppufile,locals);
  3053. end;
  3054. aktparasymtable:=oldparasymtable;
  3055. aktlocalsymtable:=oldlocalsymtable;
  3056. end;
  3057. Const
  3058. local_symtable_index : word = $8001;
  3059. function tprocdef.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  3060. var
  3061. ref : tref;
  3062. {$ifdef supportbrowser}
  3063. pdo : tobjectdef;
  3064. {$endif supportbrowser}
  3065. move_last : boolean;
  3066. d : tderef;
  3067. oldparasymtable,
  3068. oldlocalsymtable : tsymtable;
  3069. begin
  3070. d.reset;
  3071. move_last:=lastwritten=lastref;
  3072. if move_last and
  3073. (((current_module.flags and uf_local_browser)=0) or
  3074. not locals) then
  3075. exit;
  3076. oldparasymtable:=aktparasymtable;
  3077. oldlocalsymtable:=aktlocalsymtable;
  3078. aktparasymtable:=parast;
  3079. aktlocalsymtable:=localst;
  3080. { write address of this symbol }
  3081. d.build(self);
  3082. ppufile.putderef(d);
  3083. { write refs }
  3084. if assigned(lastwritten) then
  3085. ref:=lastwritten
  3086. else
  3087. ref:=defref;
  3088. while assigned(ref) do
  3089. begin
  3090. if ref.moduleindex=current_module.unit_index then
  3091. begin
  3092. ppufile.putposinfo(ref.posinfo);
  3093. ref.is_written:=true;
  3094. if move_last then
  3095. lastwritten:=ref;
  3096. end
  3097. else if not ref.is_written then
  3098. move_last:=false
  3099. else if move_last then
  3100. lastwritten:=ref;
  3101. ref:=ref.nextref;
  3102. end;
  3103. ppufile.writeentry(ibdefref);
  3104. write_references:=true;
  3105. {$ifdef supportbrowser}
  3106. if ((current_module.flags and uf_local_browser)<>0) and
  3107. assigned(localst) and
  3108. locals then
  3109. begin
  3110. pdo:=_class;
  3111. if (owner.symtabletype<>localsymtable) then
  3112. while assigned(pdo) do
  3113. begin
  3114. if pdo.symtable<>aktrecordsymtable then
  3115. begin
  3116. pdo.symtable.moduleid:=local_symtable_index;
  3117. inc(local_symtable_index);
  3118. end;
  3119. pdo:=pdo.childof;
  3120. end;
  3121. parast.moduleid:=local_symtable_index;
  3122. inc(local_symtable_index);
  3123. localst.moduleid:=local_symtable_index;
  3124. inc(local_symtable_index);
  3125. tstoredsymtable(parast).write_references(ppufile,locals);
  3126. tstoredsymtable(localst).write_references(ppufile,locals);
  3127. { decrement for }
  3128. local_symtable_index:=local_symtable_index-2;
  3129. pdo:=_class;
  3130. if (owner.symtabletype<>localsymtable) then
  3131. while assigned(pdo) do
  3132. begin
  3133. if pdo.symtable<>aktrecordsymtable then
  3134. dec(local_symtable_index);
  3135. pdo:=pdo.childof;
  3136. end;
  3137. end;
  3138. {$endif supportbrowser}
  3139. aktparasymtable:=oldparasymtable;
  3140. aktlocalsymtable:=oldlocalsymtable;
  3141. end;
  3142. procedure tprocdef.buildderef;
  3143. var
  3144. oldparasymtable,
  3145. oldlocalsymtable : tsymtable;
  3146. begin
  3147. oldparasymtable:=aktparasymtable;
  3148. oldlocalsymtable:=aktlocalsymtable;
  3149. aktparasymtable:=parast;
  3150. aktlocalsymtable:=localst;
  3151. inherited buildderef;
  3152. _classderef.build(_class);
  3153. { procsym that originaly defined this definition, should be in the
  3154. same symtable }
  3155. procsymderef.build(procsym);
  3156. {$ifdef powerpc}
  3157. { library symbol for AmigaOS/MorphOS }
  3158. libsymderef.build(libsym);
  3159. {$endif powerpc}
  3160. aktparasymtable:=oldparasymtable;
  3161. aktlocalsymtable:=oldlocalsymtable;
  3162. end;
  3163. procedure tprocdef.buildderefimpl;
  3164. var
  3165. oldparasymtable,
  3166. oldlocalsymtable : tsymtable;
  3167. begin
  3168. { released procdef? }
  3169. if not assigned(parast) then
  3170. exit;
  3171. oldparasymtable:=aktparasymtable;
  3172. oldlocalsymtable:=aktlocalsymtable;
  3173. aktparasymtable:=parast;
  3174. aktlocalsymtable:=localst;
  3175. inherited buildderefimpl;
  3176. { Locals, always build deref info it might be needed
  3177. if the unit needs to be reloaded }
  3178. if assigned(localst) then
  3179. begin
  3180. tlocalsymtable(localst).buildderef;
  3181. tlocalsymtable(localst).buildderefimpl;
  3182. end;
  3183. { inline tree }
  3184. if (po_has_inlininginfo in procoptions) then
  3185. begin
  3186. funcretsymderef.build(funcretsym);
  3187. inlininginfo^.code.buildderefimpl;
  3188. end;
  3189. aktparasymtable:=oldparasymtable;
  3190. aktlocalsymtable:=oldlocalsymtable;
  3191. end;
  3192. procedure tprocdef.deref;
  3193. var
  3194. oldparasymtable,
  3195. oldlocalsymtable : tsymtable;
  3196. begin
  3197. { released procdef? }
  3198. if not assigned(parast) then
  3199. exit;
  3200. oldparasymtable:=aktparasymtable;
  3201. oldlocalsymtable:=aktlocalsymtable;
  3202. aktparasymtable:=parast;
  3203. aktlocalsymtable:=localst;
  3204. inherited deref;
  3205. _class:=tobjectdef(_classderef.resolve);
  3206. { procsym that originaly defined this definition, should be in the
  3207. same symtable }
  3208. procsym:=tprocsym(procsymderef.resolve);
  3209. {$ifdef powerpc}
  3210. { library symbol for AmigaOS/MorphOS }
  3211. libsym:=tsym(libsymderef.resolve);
  3212. {$endif powerpc}
  3213. aktparasymtable:=oldparasymtable;
  3214. aktlocalsymtable:=oldlocalsymtable;
  3215. end;
  3216. procedure tprocdef.derefimpl;
  3217. var
  3218. oldparasymtable,
  3219. oldlocalsymtable : tsymtable;
  3220. begin
  3221. oldparasymtable:=aktparasymtable;
  3222. oldlocalsymtable:=aktlocalsymtable;
  3223. aktparasymtable:=parast;
  3224. aktlocalsymtable:=localst;
  3225. { Enable has_inlininginfo when the inlininginfo
  3226. structure is available. The has_inlininginfo was disabled
  3227. after the load, since the data was invalid }
  3228. if assigned(inlininginfo) then
  3229. include(procoptions,po_has_inlininginfo);
  3230. { Locals }
  3231. if assigned(localst) then
  3232. begin
  3233. tlocalsymtable(localst).deref;
  3234. tlocalsymtable(localst).derefimpl;
  3235. end;
  3236. { Inline }
  3237. if (po_has_inlininginfo in procoptions) then
  3238. begin
  3239. inlininginfo^.code.derefimpl;
  3240. { funcretsym, this is always located in the localst }
  3241. funcretsym:=tsym(funcretsymderef.resolve);
  3242. end
  3243. else
  3244. begin
  3245. { safety }
  3246. funcretsym:=nil;
  3247. end;
  3248. aktparasymtable:=oldparasymtable;
  3249. aktlocalsymtable:=oldlocalsymtable;
  3250. end;
  3251. function tprocdef.gettypename : string;
  3252. begin
  3253. gettypename := FullProcName(false);
  3254. end;
  3255. function tprocdef.mangledname : string;
  3256. var
  3257. hp : TParavarsym;
  3258. hs : string;
  3259. crc : dword;
  3260. newlen,
  3261. oldlen,
  3262. i : integer;
  3263. begin
  3264. if assigned(_mangledname) then
  3265. begin
  3266. {$ifdef compress}
  3267. mangledname:=minilzw_decode(_mangledname^);
  3268. {$else}
  3269. mangledname:=_mangledname^;
  3270. {$endif}
  3271. exit;
  3272. end;
  3273. { we need to use the symtable where the procsym is inserted,
  3274. because that is visible to the world }
  3275. mangledname:=make_mangledname('',procsym.owner,procsym.name);
  3276. oldlen:=length(mangledname);
  3277. { add parameter types }
  3278. for i:=0 to paras.count-1 do
  3279. begin
  3280. hp:=tparavarsym(paras[i]);
  3281. if not(vo_is_hidden_para in hp.varoptions) then
  3282. mangledname:=mangledname+'$'+hp.vartype.def.mangledparaname;
  3283. end;
  3284. { add resulttype, add $$ as separator to make it unique from a
  3285. parameter separator }
  3286. if not is_void(rettype.def) then
  3287. mangledname:=mangledname+'$$'+rettype.def.mangledparaname;
  3288. newlen:=length(mangledname);
  3289. { Replace with CRC if the parameter line is very long }
  3290. if (newlen-oldlen>12) and
  3291. ((newlen>128) or (newlen-oldlen>64)) then
  3292. begin
  3293. crc:=$ffffffff;
  3294. for i:=0 to paras.count-1 do
  3295. begin
  3296. hp:=tparavarsym(paras[i]);
  3297. if not(vo_is_hidden_para in hp.varoptions) then
  3298. begin
  3299. hs:=hp.vartype.def.mangledparaname;
  3300. crc:=UpdateCrc32(crc,hs[1],length(hs));
  3301. end;
  3302. end;
  3303. hs:=hp.vartype.def.mangledparaname;
  3304. crc:=UpdateCrc32(crc,hs[1],length(hs));
  3305. mangledname:=Copy(mangledname,1,oldlen)+'$crc'+hexstr(crc,8);
  3306. end;
  3307. {$ifdef compress}
  3308. _mangledname:=stringdup(minilzw_encode(mangledname));
  3309. {$else}
  3310. _mangledname:=stringdup(mangledname);
  3311. {$endif}
  3312. end;
  3313. function tprocdef.cplusplusmangledname : string;
  3314. function getcppparaname(p : tdef) : string;
  3315. const
  3316. ordtype2str : array[tbasetype] of string[2] = (
  3317. '',
  3318. 'Uc','Us','Ui','Us',
  3319. 'Sc','s','i','x',
  3320. 'b','b','b',
  3321. 'c','w','x');
  3322. var
  3323. s : string;
  3324. begin
  3325. case p.deftype of
  3326. orddef:
  3327. s:=ordtype2str[torddef(p).typ];
  3328. pointerdef:
  3329. s:='P'+getcppparaname(tpointerdef(p).pointertype.def);
  3330. else
  3331. internalerror(2103001);
  3332. end;
  3333. getcppparaname:=s;
  3334. end;
  3335. var
  3336. s,s2 : string;
  3337. hp : TParavarsym;
  3338. i : integer;
  3339. begin
  3340. s := procsym.realname;
  3341. if procsym.owner.symtabletype=objectsymtable then
  3342. begin
  3343. s2:=upper(tobjectdef(procsym.owner.defowner).typesym.realname);
  3344. case proctypeoption of
  3345. potype_destructor:
  3346. s:='_$_'+tostr(length(s2))+s2;
  3347. potype_constructor:
  3348. s:='___'+tostr(length(s2))+s2;
  3349. else
  3350. s:='_'+s+'__'+tostr(length(s2))+s2;
  3351. end;
  3352. end
  3353. else s:=s+'__';
  3354. s:=s+'F';
  3355. { concat modifiers }
  3356. { !!!!! }
  3357. { now we handle the parameters }
  3358. if maxparacount>0 then
  3359. begin
  3360. for i:=0 to paras.count-1 do
  3361. begin
  3362. hp:=tparavarsym(paras[i]);
  3363. s2:=getcppparaname(hp.vartype.def);
  3364. if hp.varspez in [vs_var,vs_out] then
  3365. s2:='R'+s2;
  3366. s:=s+s2;
  3367. end;
  3368. end
  3369. else
  3370. s:=s+'v';
  3371. cplusplusmangledname:=s;
  3372. end;
  3373. procedure tprocdef.setmangledname(const s : string);
  3374. begin
  3375. { This is not allowed anymore, the forward declaration
  3376. already needs to create the correct mangledname, no changes
  3377. afterwards are allowed (PFV) }
  3378. { Exception: interface definitions in mode macpas, since in that }
  3379. { case no reference to the old name can exist yet (JM) }
  3380. if assigned(_mangledname) then
  3381. if ((m_mac in aktmodeswitches) and
  3382. (interfacedef)) then
  3383. stringdispose(_mangledname)
  3384. else
  3385. internalerror(200411171);
  3386. {$ifdef compress}
  3387. _mangledname:=stringdup(minilzw_encode(s));
  3388. {$else}
  3389. _mangledname:=stringdup(s);
  3390. {$endif}
  3391. include(procoptions,po_has_mangledname);
  3392. end;
  3393. {***************************************************************************
  3394. TPROCVARDEF
  3395. ***************************************************************************}
  3396. constructor tprocvardef.create(level:byte);
  3397. begin
  3398. inherited create(procvardef,level);
  3399. end;
  3400. constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
  3401. begin
  3402. inherited ppuload(procvardef,ppufile);
  3403. { load para symtable }
  3404. parast:=tparasymtable.create(unknown_level);
  3405. tparasymtable(parast).ppuload(ppufile);
  3406. parast.defowner:=self;
  3407. end;
  3408. function tprocvardef.getcopy : tstoreddef;
  3409. begin
  3410. result:=self;
  3411. (*
  3412. { saves a definition to the return type }
  3413. rettype : ttype;
  3414. parast : tsymtable;
  3415. paras : tparalist;
  3416. proctypeoption : tproctypeoption;
  3417. proccalloption : tproccalloption;
  3418. procoptions : tprocoptions;
  3419. requiredargarea : aint;
  3420. { number of user visibile parameters }
  3421. maxparacount,
  3422. minparacount : byte;
  3423. {$ifdef i386}
  3424. fpu_used : longint; { how many stack fpu must be empty }
  3425. {$endif i386}
  3426. funcretloc : array[tcallercallee] of TLocation;
  3427. has_paraloc_info : boolean; { paraloc info is available }
  3428. tprocvardef = class(tabstractprocdef)
  3429. constructor create(level:byte);
  3430. constructor ppuload(ppufile:tcompilerppufile);
  3431. function getcopy : tstoreddef;override;
  3432. *)
  3433. end;
  3434. procedure tprocvardef.ppuwrite(ppufile:tcompilerppufile);
  3435. var
  3436. oldparasymtable,
  3437. oldlocalsymtable : tsymtable;
  3438. begin
  3439. oldparasymtable:=aktparasymtable;
  3440. oldlocalsymtable:=aktlocalsymtable;
  3441. aktparasymtable:=parast;
  3442. aktlocalsymtable:=nil;
  3443. { here we cannot get a real good value so just give something }
  3444. { plausible (PM) }
  3445. { a more secure way would be
  3446. to allways store in a temp }
  3447. {$ifdef i386}
  3448. if is_fpu(rettype.def) then
  3449. fpu_used:={2}maxfpuregs
  3450. else
  3451. fpu_used:=0;
  3452. {$endif i386}
  3453. inherited ppuwrite(ppufile);
  3454. { Write this entry }
  3455. ppufile.writeentry(ibprocvardef);
  3456. { Save the para symtable, this is taken from the interface }
  3457. tparasymtable(parast).ppuwrite(ppufile);
  3458. aktparasymtable:=oldparasymtable;
  3459. aktlocalsymtable:=oldlocalsymtable;
  3460. end;
  3461. procedure tprocvardef.buildderef;
  3462. var
  3463. oldparasymtable,
  3464. oldlocalsymtable : tsymtable;
  3465. begin
  3466. oldparasymtable:=aktparasymtable;
  3467. oldlocalsymtable:=aktlocalsymtable;
  3468. aktparasymtable:=parast;
  3469. aktlocalsymtable:=nil;
  3470. inherited buildderef;
  3471. aktparasymtable:=oldparasymtable;
  3472. aktlocalsymtable:=oldlocalsymtable;
  3473. end;
  3474. procedure tprocvardef.deref;
  3475. var
  3476. oldparasymtable,
  3477. oldlocalsymtable : tsymtable;
  3478. begin
  3479. oldparasymtable:=aktparasymtable;
  3480. oldlocalsymtable:=aktlocalsymtable;
  3481. aktparasymtable:=parast;
  3482. aktlocalsymtable:=nil;
  3483. inherited deref;
  3484. aktparasymtable:=oldparasymtable;
  3485. aktlocalsymtable:=oldlocalsymtable;
  3486. end;
  3487. function tprocvardef.getsymtable(t:tgetsymtable):tsymtable;
  3488. begin
  3489. case t of
  3490. gs_para :
  3491. getsymtable:=parast;
  3492. else
  3493. getsymtable:=nil;
  3494. end;
  3495. end;
  3496. function tprocvardef.size : aint;
  3497. begin
  3498. if (po_methodpointer in procoptions) and
  3499. not(po_addressonly in procoptions) then
  3500. size:=2*sizeof(aint)
  3501. else
  3502. size:=sizeof(aint);
  3503. end;
  3504. function tprocvardef.is_methodpointer:boolean;
  3505. begin
  3506. result:=(po_methodpointer in procoptions);
  3507. end;
  3508. function tprocvardef.is_addressonly:boolean;
  3509. begin
  3510. result:=not(po_methodpointer in procoptions) or
  3511. (po_addressonly in procoptions);
  3512. end;
  3513. function tprocvardef.getmangledparaname:string;
  3514. begin
  3515. result:='procvar';
  3516. end;
  3517. procedure tprocvardef.write_rtti_data(rt:trttitype);
  3518. procedure write_para(parasym:tparavarsym);
  3519. var
  3520. paraspec : byte;
  3521. begin
  3522. { only store user visible parameters }
  3523. if not(vo_is_hidden_para in parasym.varoptions) then
  3524. begin
  3525. case parasym.varspez of
  3526. vs_value: paraspec := 0;
  3527. vs_const: paraspec := pfConst;
  3528. vs_var : paraspec := pfVar;
  3529. vs_out : paraspec := pfOut;
  3530. end;
  3531. { write flags for current parameter }
  3532. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(paraspec));
  3533. { write name of current parameter }
  3534. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(parasym.realname)));
  3535. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(parasym.realname));
  3536. { write name of type of current parameter }
  3537. tstoreddef(parasym.vartype.def).write_rtti_name;
  3538. end;
  3539. end;
  3540. var
  3541. methodkind : byte;
  3542. i : integer;
  3543. begin
  3544. if po_methodpointer in procoptions then
  3545. begin
  3546. { write method id and name }
  3547. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkmethod));
  3548. write_rtti_name;
  3549. {$ifdef cpurequiresproperalignment}
  3550. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  3551. {$endif cpurequiresproperalignment}
  3552. { write kind of method (can only be function or procedure)}
  3553. if rettype.def = voidtype.def then
  3554. methodkind := mkProcedure
  3555. else
  3556. methodkind := mkFunction;
  3557. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(methodkind));
  3558. { get # of parameters }
  3559. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(maxparacount));
  3560. { write parameter info. The parameters must be written in reverse order
  3561. if this method uses right to left parameter pushing! }
  3562. if proccalloption in pushleftright_pocalls then
  3563. begin
  3564. for i:=0 to paras.count-1 do
  3565. write_para(tparavarsym(paras[i]));
  3566. end
  3567. else
  3568. begin
  3569. for i:=paras.count-1 downto 0 do
  3570. write_para(tparavarsym(paras[i]));
  3571. end;
  3572. { write name of result type }
  3573. tstoreddef(rettype.def).write_rtti_name;
  3574. end
  3575. else
  3576. begin
  3577. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkprocvar));
  3578. write_rtti_name;
  3579. end;
  3580. end;
  3581. function tprocvardef.is_publishable : boolean;
  3582. begin
  3583. is_publishable:=(po_methodpointer in procoptions);
  3584. end;
  3585. function tprocvardef.gettypename : string;
  3586. var
  3587. s: string;
  3588. showhidden : boolean;
  3589. begin
  3590. {$ifdef EXTDEBUG}
  3591. showhidden:=true;
  3592. {$else EXTDEBUG}
  3593. showhidden:=false;
  3594. {$endif EXTDEBUG}
  3595. s:='<';
  3596. if po_classmethod in procoptions then
  3597. s := s+'class method type of'
  3598. else
  3599. if po_addressonly in procoptions then
  3600. s := s+'address of'
  3601. else
  3602. s := s+'procedure variable type of';
  3603. if po_local in procoptions then
  3604. s := s+' local';
  3605. if assigned(rettype.def) and
  3606. (rettype.def<>voidtype.def) then
  3607. s:=s+' function'+typename_paras(showhidden)+':'+rettype.def.gettypename
  3608. else
  3609. s:=s+' procedure'+typename_paras(showhidden);
  3610. if po_methodpointer in procoptions then
  3611. s := s+' of object';
  3612. gettypename := s+';'+ProcCallOptionStr[proccalloption]+'>';
  3613. end;
  3614. {***************************************************************************
  3615. TOBJECTDEF
  3616. ***************************************************************************}
  3617. type
  3618. tproptablelistitem = class(TLinkedListItem)
  3619. index : longint;
  3620. def : tobjectdef;
  3621. end;
  3622. tpropnamelistitem = class(TLinkedListItem)
  3623. index : longint;
  3624. name : stringid;
  3625. owner : tsymtable;
  3626. end;
  3627. var
  3628. proptablelist : tlinkedlist;
  3629. propnamelist : tlinkedlist;
  3630. function searchproptablelist(p : tobjectdef) : tproptablelistitem;
  3631. var
  3632. hp : tproptablelistitem;
  3633. begin
  3634. hp:=tproptablelistitem(proptablelist.first);
  3635. while assigned(hp) do
  3636. if hp.def=p then
  3637. begin
  3638. result:=hp;
  3639. exit;
  3640. end
  3641. else
  3642. hp:=tproptablelistitem(hp.next);
  3643. result:=nil;
  3644. end;
  3645. function searchpropnamelist(const n:string) : tpropnamelistitem;
  3646. var
  3647. hp : tpropnamelistitem;
  3648. begin
  3649. hp:=tpropnamelistitem(propnamelist.first);
  3650. while assigned(hp) do
  3651. if hp.name=n then
  3652. begin
  3653. result:=hp;
  3654. exit;
  3655. end
  3656. else
  3657. hp:=tpropnamelistitem(hp.next);
  3658. result:=nil;
  3659. end;
  3660. constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  3661. begin
  3662. inherited create(objectdef);
  3663. objecttype:=ot;
  3664. objectoptions:=[];
  3665. childof:=nil;
  3666. symtable:=tobjectsymtable.create(n,aktpackrecords);
  3667. { create space for vmt !! }
  3668. vmt_offset:=0;
  3669. symtable.defowner:=self;
  3670. lastvtableindex:=0;
  3671. set_parent(c);
  3672. objname:=stringdup(upper(n));
  3673. objrealname:=stringdup(n);
  3674. if objecttype in [odt_interfacecorba,odt_interfacecom,odt_dispinterface] then
  3675. prepareguid;
  3676. { setup implemented interfaces }
  3677. if objecttype in [odt_class,odt_interfacecorba] then
  3678. implementedinterfaces:=timplementedinterfaces.create
  3679. else
  3680. implementedinterfaces:=nil;
  3681. writing_class_record_dbginfo:=false;
  3682. end;
  3683. constructor tobjectdef.ppuload(ppufile:tcompilerppufile);
  3684. var
  3685. i,implintfcount: longint;
  3686. d : tderef;
  3687. begin
  3688. inherited ppuload(objectdef,ppufile);
  3689. objecttype:=tobjectdeftype(ppufile.getbyte);
  3690. objrealname:=stringdup(ppufile.getstring);
  3691. objname:=stringdup(upper(objrealname^));
  3692. symtable:=tobjectsymtable.create(objrealname^,0);
  3693. tobjectsymtable(symtable).datasize:=ppufile.getaint;
  3694. tobjectsymtable(symtable).fieldalignment:=ppufile.getbyte;
  3695. tobjectsymtable(symtable).recordalignment:=ppufile.getbyte;
  3696. vmt_offset:=ppufile.getlongint;
  3697. ppufile.getderef(childofderef);
  3698. ppufile.getsmallset(objectoptions);
  3699. { load guid }
  3700. iidstr:=nil;
  3701. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3702. begin
  3703. new(iidguid);
  3704. ppufile.getguid(iidguid^);
  3705. iidstr:=stringdup(ppufile.getstring);
  3706. lastvtableindex:=ppufile.getlongint;
  3707. end;
  3708. { load implemented interfaces }
  3709. if objecttype in [odt_class,odt_interfacecorba] then
  3710. begin
  3711. implementedinterfaces:=timplementedinterfaces.create;
  3712. implintfcount:=ppufile.getlongint;
  3713. for i:=1 to implintfcount do
  3714. begin
  3715. ppufile.getderef(d);
  3716. implementedinterfaces.addintf_deref(d,ppufile.getlongint);
  3717. end;
  3718. end
  3719. else
  3720. implementedinterfaces:=nil;
  3721. tobjectsymtable(symtable).ppuload(ppufile);
  3722. symtable.defowner:=self;
  3723. { handles the predefined class tobject }
  3724. { the last TOBJECT which is loaded gets }
  3725. { it ! }
  3726. if (childof=nil) and
  3727. (objecttype=odt_class) and
  3728. (objname^='TOBJECT') then
  3729. class_tobject:=self;
  3730. if (childof=nil) and
  3731. (objecttype=odt_interfacecom) and
  3732. (objname^='IUNKNOWN') then
  3733. interface_iunknown:=self;
  3734. writing_class_record_dbginfo:=false;
  3735. end;
  3736. destructor tobjectdef.destroy;
  3737. begin
  3738. if assigned(symtable) then
  3739. symtable.free;
  3740. stringdispose(objname);
  3741. stringdispose(objrealname);
  3742. if assigned(iidstr) then
  3743. stringdispose(iidstr);
  3744. if assigned(implementedinterfaces) then
  3745. implementedinterfaces.free;
  3746. if assigned(iidguid) then
  3747. dispose(iidguid);
  3748. inherited destroy;
  3749. end;
  3750. function tobjectdef.getcopy : tstoreddef;
  3751. var
  3752. i,
  3753. implintfcount : longint;
  3754. begin
  3755. result:=tobjectdef.create(objecttype,objname^,childof);
  3756. tobjectdef(result).symtable:=symtable.getcopy;
  3757. if assigned(objname) then
  3758. tobjectdef(result).objname:=stringdup(objname^);
  3759. if assigned(objrealname) then
  3760. tobjectdef(result).objrealname:=stringdup(objrealname^);
  3761. tobjectdef(result).objectoptions:=objectoptions;
  3762. tobjectdef(result).vmt_offset:=vmt_offset;
  3763. if assigned(iidguid) then
  3764. begin
  3765. new(tobjectdef(result).iidguid);
  3766. move(iidguid^,tobjectdef(result).iidguid^,sizeof(iidguid^));
  3767. end;
  3768. if assigned(iidstr) then
  3769. tobjectdef(result).iidstr:=stringdup(iidstr^);
  3770. tobjectdef(result).lastvtableindex:=lastvtableindex;
  3771. if assigned(implementedinterfaces) then
  3772. begin
  3773. implintfcount:=implementedinterfaces.count;
  3774. for i:=1 to implintfcount do
  3775. begin
  3776. tobjectdef(result).implementedinterfaces.addintf_ioffset(implementedinterfaces.interfaces(i),
  3777. implementedinterfaces.ioffsets(i));
  3778. end;
  3779. end;
  3780. end;
  3781. procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile);
  3782. var
  3783. implintfcount : longint;
  3784. i : longint;
  3785. begin
  3786. inherited ppuwrite(ppufile);
  3787. ppufile.putbyte(byte(objecttype));
  3788. ppufile.putstring(objrealname^);
  3789. ppufile.putaint(tobjectsymtable(symtable).datasize);
  3790. ppufile.putbyte(tobjectsymtable(symtable).fieldalignment);
  3791. ppufile.putbyte(tobjectsymtable(symtable).recordalignment);
  3792. ppufile.putlongint(vmt_offset);
  3793. ppufile.putderef(childofderef);
  3794. ppufile.putsmallset(objectoptions);
  3795. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3796. begin
  3797. ppufile.putguid(iidguid^);
  3798. ppufile.putstring(iidstr^);
  3799. ppufile.putlongint(lastvtableindex);
  3800. end;
  3801. if objecttype in [odt_class,odt_interfacecorba] then
  3802. begin
  3803. implintfcount:=implementedinterfaces.count;
  3804. ppufile.putlongint(implintfcount);
  3805. for i:=1 to implintfcount do
  3806. begin
  3807. ppufile.putderef(implementedinterfaces.interfacesderef(i));
  3808. ppufile.putlongint(implementedinterfaces.ioffsets(i));
  3809. end;
  3810. end;
  3811. ppufile.writeentry(ibobjectdef);
  3812. tobjectsymtable(symtable).ppuwrite(ppufile);
  3813. end;
  3814. function tobjectdef.gettypename:string;
  3815. begin
  3816. if (self <> aktobjectdef) then
  3817. gettypename:=typename
  3818. else
  3819. { in this case we will go in endless recursion, because then }
  3820. { there is no tsym associated yet with the def. It can occur }
  3821. { (tests/webtbf/tw4757.pp), so for now give a generic name }
  3822. { instead of the actual type name }
  3823. gettypename:='<Currently Parsed Class>';
  3824. end;
  3825. procedure tobjectdef.buildderef;
  3826. var
  3827. oldrecsyms : tsymtable;
  3828. begin
  3829. inherited buildderef;
  3830. childofderef.build(childof);
  3831. oldrecsyms:=aktrecordsymtable;
  3832. aktrecordsymtable:=symtable;
  3833. tstoredsymtable(symtable).buildderef;
  3834. aktrecordsymtable:=oldrecsyms;
  3835. if objecttype in [odt_class,odt_interfacecorba] then
  3836. implementedinterfaces.buildderef;
  3837. end;
  3838. procedure tobjectdef.deref;
  3839. var
  3840. oldrecsyms : tsymtable;
  3841. begin
  3842. inherited deref;
  3843. childof:=tobjectdef(childofderef.resolve);
  3844. oldrecsyms:=aktrecordsymtable;
  3845. aktrecordsymtable:=symtable;
  3846. tstoredsymtable(symtable).deref;
  3847. aktrecordsymtable:=oldrecsyms;
  3848. if objecttype in [odt_class,odt_interfacecorba] then
  3849. implementedinterfaces.deref;
  3850. end;
  3851. function tobjectdef.getparentdef:tdef;
  3852. begin
  3853. {$warning TODO Remove getparentdef hack}
  3854. { With 2 forward declared classes with the child class before the
  3855. parent class the child class is written earlier to the ppu. Leaving it
  3856. possible to have a reference to the parent class for property overriding,
  3857. but the parent class still has the childof not resolved yet (PFV) }
  3858. if childof=nil then
  3859. childof:=tobjectdef(childofderef.resolve);
  3860. result:=childof;
  3861. end;
  3862. procedure tobjectdef.prepareguid;
  3863. begin
  3864. { set up guid }
  3865. if not assigned(iidguid) then
  3866. begin
  3867. new(iidguid);
  3868. fillchar(iidguid^,sizeof(iidguid^),0); { default null guid }
  3869. end;
  3870. { setup iidstring }
  3871. if not assigned(iidstr) then
  3872. iidstr:=stringdup(''); { default is empty string }
  3873. end;
  3874. procedure tobjectdef.set_parent( c : tobjectdef);
  3875. begin
  3876. { nothing to do if the parent was not forward !}
  3877. if assigned(childof) then
  3878. exit;
  3879. childof:=c;
  3880. { some options are inherited !! }
  3881. if assigned(c) then
  3882. begin
  3883. { only important for classes }
  3884. lastvtableindex:=c.lastvtableindex;
  3885. objectoptions:=objectoptions+(c.objectoptions*
  3886. inherited_objectoptions);
  3887. if not (objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) then
  3888. begin
  3889. { add the data of the anchestor class }
  3890. inc(tobjectsymtable(symtable).datasize,tobjectsymtable(c.symtable).datasize);
  3891. if (oo_has_vmt in objectoptions) and
  3892. (oo_has_vmt in c.objectoptions) then
  3893. dec(tobjectsymtable(symtable).datasize,sizeof(aint));
  3894. { if parent has a vmt field then
  3895. the offset is the same for the child PM }
  3896. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  3897. begin
  3898. vmt_offset:=c.vmt_offset;
  3899. include(objectoptions,oo_has_vmt);
  3900. end;
  3901. end;
  3902. end;
  3903. end;
  3904. procedure tobjectdef.insertvmt;
  3905. begin
  3906. if objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3907. exit;
  3908. if (oo_has_vmt in objectoptions) then
  3909. internalerror(12345)
  3910. else
  3911. begin
  3912. tobjectsymtable(symtable).datasize:=align(tobjectsymtable(symtable).datasize,
  3913. tobjectsymtable(symtable).fieldalignment);
  3914. {$ifdef cpurequiresproperalignment}
  3915. tobjectsymtable(symtable).datasize:=align(tobjectsymtable(symtable).datasize,sizeof(aint));
  3916. {$endif cpurequiresproperalignment}
  3917. vmt_offset:=tobjectsymtable(symtable).datasize;
  3918. inc(tobjectsymtable(symtable).datasize,sizeof(aint));
  3919. include(objectoptions,oo_has_vmt);
  3920. end;
  3921. end;
  3922. procedure tobjectdef.check_forwards;
  3923. begin
  3924. if not(objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface]) then
  3925. tstoredsymtable(symtable).check_forwards;
  3926. if (oo_is_forward in objectoptions) then
  3927. begin
  3928. { ok, in future, the forward can be resolved }
  3929. Message1(sym_e_class_forward_not_resolved,objrealname^);
  3930. exclude(objectoptions,oo_is_forward);
  3931. end;
  3932. end;
  3933. { true, if self inherits from d (or if they are equal) }
  3934. function tobjectdef.is_related(d : tdef) : boolean;
  3935. var
  3936. hp : tobjectdef;
  3937. begin
  3938. hp:=self;
  3939. while assigned(hp) do
  3940. begin
  3941. if hp=d then
  3942. begin
  3943. is_related:=true;
  3944. exit;
  3945. end;
  3946. hp:=hp.childof;
  3947. end;
  3948. is_related:=false;
  3949. end;
  3950. procedure _searchdestructor(sym:Tnamedindexitem;sd:pointer);
  3951. begin
  3952. { if we found already a destructor, then we exit }
  3953. if (ppointer(sd)^=nil) and
  3954. (Tsym(sym).typ=procsym) then
  3955. ppointer(sd)^:=Tprocsym(sym).search_procdef_bytype(potype_destructor);
  3956. end;
  3957. function tobjectdef.searchdestructor : tprocdef;
  3958. var
  3959. o : tobjectdef;
  3960. sd : tprocdef;
  3961. begin
  3962. searchdestructor:=nil;
  3963. o:=self;
  3964. sd:=nil;
  3965. while assigned(o) do
  3966. begin
  3967. o.symtable.foreach_static(@_searchdestructor,@sd);
  3968. if assigned(sd) then
  3969. begin
  3970. searchdestructor:=sd;
  3971. exit;
  3972. end;
  3973. o:=o.childof;
  3974. end;
  3975. end;
  3976. function tobjectdef.size : aint;
  3977. begin
  3978. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3979. result:=sizeof(aint)
  3980. else
  3981. result:=tobjectsymtable(symtable).datasize;
  3982. end;
  3983. function tobjectdef.alignment:shortint;
  3984. begin
  3985. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface] then
  3986. alignment:=sizeof(aint)
  3987. else
  3988. alignment:=tobjectsymtable(symtable).recordalignment;
  3989. end;
  3990. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3991. begin
  3992. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3993. case objecttype of
  3994. odt_class:
  3995. { the +2*sizeof(Aint) is size and -size }
  3996. vmtmethodoffset:=(index+10)*sizeof(aint)+2*sizeof(AInt);
  3997. odt_interfacecom,odt_interfacecorba:
  3998. vmtmethodoffset:=index*sizeof(aint);
  3999. else
  4000. {$ifdef WITHDMT}
  4001. vmtmethodoffset:=(index+4)*sizeof(aint);
  4002. {$else WITHDMT}
  4003. vmtmethodoffset:=(index+3)*sizeof(aint);
  4004. {$endif WITHDMT}
  4005. end;
  4006. end;
  4007. function tobjectdef.vmt_mangledname : string;
  4008. begin
  4009. if not(oo_has_vmt in objectoptions) then
  4010. Message1(parser_n_object_has_no_vmt,objrealname^);
  4011. vmt_mangledname:=make_mangledname('VMT',owner,objname^);
  4012. end;
  4013. function tobjectdef.rtti_name : string;
  4014. begin
  4015. rtti_name:=make_mangledname('RTTI',owner,objname^);
  4016. end;
  4017. function tobjectdef.needs_inittable : boolean;
  4018. begin
  4019. case objecttype of
  4020. odt_dispinterface,
  4021. odt_class :
  4022. needs_inittable:=false;
  4023. odt_interfacecom:
  4024. needs_inittable:=true;
  4025. odt_interfacecorba:
  4026. needs_inittable:=is_related(interface_iunknown);
  4027. odt_object:
  4028. needs_inittable:=tobjectsymtable(symtable).needs_init_final;
  4029. else
  4030. internalerror(200108267);
  4031. end;
  4032. end;
  4033. function tobjectdef.members_need_inittable : boolean;
  4034. begin
  4035. members_need_inittable:=tobjectsymtable(symtable).needs_init_final;
  4036. end;
  4037. procedure tobjectdef.collect_published_properties(sym:tnamedindexitem;arg:pointer);
  4038. var
  4039. hp : tpropnamelistitem;
  4040. begin
  4041. if (tsym(sym).typ=propertysym) and
  4042. (sp_published in tsym(sym).symoptions) then
  4043. begin
  4044. hp:=searchpropnamelist(tsym(sym).name);
  4045. if not(assigned(hp)) then
  4046. begin
  4047. hp:=tpropnamelistitem.create;
  4048. hp.name:=tsym(sym).name;
  4049. hp.index:=propnamelist.count;
  4050. hp.owner:=tsym(sym).owner;
  4051. propnamelist.concat(hp);
  4052. end;
  4053. end;
  4054. end;
  4055. procedure tobjectdef.count_published_properties(sym:tnamedindexitem;arg:pointer);
  4056. begin
  4057. if (tsym(sym).typ=propertysym) and
  4058. (sp_published in tsym(sym).symoptions) then
  4059. inc(plongint(arg)^);
  4060. end;
  4061. procedure tobjectdef.write_property_info(sym : tnamedindexitem;arg:pointer);
  4062. var
  4063. proctypesinfo : byte;
  4064. propnameitem : tpropnamelistitem;
  4065. procedure writeproc(proc : tsymlist; shiftvalue : byte);
  4066. var
  4067. typvalue : byte;
  4068. hp : psymlistitem;
  4069. address : longint;
  4070. def : tdef;
  4071. begin
  4072. if not(assigned(proc) and assigned(proc.firstsym)) then
  4073. begin
  4074. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,1));
  4075. typvalue:=3;
  4076. end
  4077. else if proc.firstsym^.sym.typ=fieldvarsym then
  4078. begin
  4079. address:=0;
  4080. hp:=proc.firstsym;
  4081. def:=nil;
  4082. while assigned(hp) do
  4083. begin
  4084. case hp^.sltype of
  4085. sl_load :
  4086. begin
  4087. def:=tfieldvarsym(hp^.sym).vartype.def;
  4088. inc(address,tfieldvarsym(hp^.sym).fieldoffset);
  4089. end;
  4090. sl_subscript :
  4091. begin
  4092. if not(assigned(def) and (def.deftype=recorddef)) then
  4093. internalerror(200402171);
  4094. inc(address,tfieldvarsym(hp^.sym).fieldoffset);
  4095. def:=tfieldvarsym(hp^.sym).vartype.def;
  4096. end;
  4097. sl_vec :
  4098. begin
  4099. if not(assigned(def) and (def.deftype=arraydef)) then
  4100. internalerror(200402172);
  4101. def:=tarraydef(def).elementtype.def;
  4102. inc(address,def.size*hp^.value);
  4103. end;
  4104. end;
  4105. hp:=hp^.next;
  4106. end;
  4107. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,address));
  4108. typvalue:=0;
  4109. end
  4110. else
  4111. begin
  4112. { When there was an error then procdef is not assigned }
  4113. if not assigned(proc.procdef) then
  4114. exit;
  4115. if not(po_virtualmethod in tprocdef(proc.procdef).procoptions) then
  4116. begin
  4117. current_asmdata.asmlists[al_rtti].concat(Tai_const.createname(tprocdef(proc.procdef).mangledname,0));
  4118. typvalue:=1;
  4119. end
  4120. else
  4121. begin
  4122. { virtual method, write vmt offset }
  4123. current_asmdata.asmlists[al_rtti].concat(Tai_const.create(aitconst_ptr,
  4124. tprocdef(proc.procdef)._class.vmtmethodoffset(tprocdef(proc.procdef).extnumber)));
  4125. typvalue:=2;
  4126. end;
  4127. end;
  4128. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4129. end;
  4130. begin
  4131. if (tsym(sym).typ=propertysym) and
  4132. (sp_published in tsym(sym).symoptions) then
  4133. begin
  4134. if ppo_indexed in tpropertysym(sym).propoptions then
  4135. proctypesinfo:=$40
  4136. else
  4137. proctypesinfo:=0;
  4138. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti)));
  4139. writeproc(tpropertysym(sym).readaccess,0);
  4140. writeproc(tpropertysym(sym).writeaccess,2);
  4141. { isn't it stored ? }
  4142. if not(ppo_stored in tpropertysym(sym).propoptions) then
  4143. begin
  4144. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  4145. proctypesinfo:=proctypesinfo or (3 shl 4);
  4146. end
  4147. else
  4148. writeproc(tpropertysym(sym).storedaccess,4);
  4149. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  4150. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  4151. propnameitem:=searchpropnamelist(tpropertysym(sym).name);
  4152. if not assigned(propnameitem) then
  4153. internalerror(200512201);
  4154. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnameitem.index));
  4155. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(proctypesinfo));
  4156. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  4157. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(tpropertysym(sym).realname));
  4158. {$ifdef cpurequiresproperalignment}
  4159. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4160. {$endif cpurequiresproperalignment}
  4161. end;
  4162. end;
  4163. procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
  4164. begin
  4165. if needs_prop_entry(tsym(sym)) then
  4166. begin
  4167. case tsym(sym).typ of
  4168. propertysym:
  4169. tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti);
  4170. fieldvarsym:
  4171. tstoreddef(tfieldvarsym(sym).vartype.def).get_rtti_label(fullrtti);
  4172. else
  4173. internalerror(1509991);
  4174. end;
  4175. end;
  4176. end;
  4177. procedure tobjectdef.write_child_rtti_data(rt:trttitype);
  4178. begin
  4179. FRTTIType:=rt;
  4180. case rt of
  4181. initrtti :
  4182. symtable.foreach(@generate_field_rtti,nil);
  4183. fullrtti :
  4184. symtable.foreach(@generate_published_child_rtti,nil);
  4185. else
  4186. internalerror(200108301);
  4187. end;
  4188. end;
  4189. procedure tobjectdef.count_published_fields(sym:tnamedindexitem;arg:pointer);
  4190. var
  4191. hp : tproptablelistitem;
  4192. begin
  4193. if (tsym(sym).typ=fieldvarsym) and
  4194. (sp_published in tsym(sym).symoptions) then
  4195. begin
  4196. if tfieldvarsym(sym).vartype.def.deftype<>objectdef then
  4197. internalerror(0206001);
  4198. hp:=searchproptablelist(tobjectdef(tfieldvarsym(sym).vartype.def));
  4199. if not(assigned(hp)) then
  4200. begin
  4201. hp:=tproptablelistitem.create;
  4202. hp.def:=tobjectdef(tfieldvarsym(sym).vartype.def);
  4203. hp.index:=proptablelist.count+1;
  4204. proptablelist.concat(hp);
  4205. end;
  4206. inc(plongint(arg)^);
  4207. end;
  4208. end;
  4209. procedure tobjectdef.writefields(sym:tnamedindexitem;arg:pointer);
  4210. var
  4211. hp : tproptablelistitem;
  4212. begin
  4213. if needs_prop_entry(tsym(sym)) and
  4214. (tsym(sym).typ=fieldvarsym) then
  4215. begin
  4216. {$ifdef cpurequiresproperalignment}
  4217. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(AInt)));
  4218. {$endif cpurequiresproperalignment}
  4219. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_aint(tfieldvarsym(sym).fieldoffset));
  4220. hp:=searchproptablelist(tobjectdef(tfieldvarsym(sym).vartype.def));
  4221. if not(assigned(hp)) then
  4222. internalerror(0206002);
  4223. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(hp.index));
  4224. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(tfieldvarsym(sym).realname)));
  4225. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(tfieldvarsym(sym).realname));
  4226. end;
  4227. end;
  4228. function tobjectdef.generate_field_table : tasmlabel;
  4229. var
  4230. fieldtable,
  4231. classtable : tasmlabel;
  4232. hp : tproptablelistitem;
  4233. fieldcount : longint;
  4234. begin
  4235. proptablelist:=TLinkedList.Create;
  4236. current_asmdata.getdatalabel(fieldtable);
  4237. current_asmdata.getdatalabel(classtable);
  4238. maybe_new_object_file(current_asmdata.asmlists[al_rtti]);
  4239. new_section(current_asmdata.asmlists[al_rtti],sec_rodata,classtable.name,const_align(sizeof(aint)));
  4240. { fields }
  4241. fieldcount:=0;
  4242. symtable.foreach(@count_published_fields,@fieldcount);
  4243. current_asmdata.asmlists[al_rtti].concat(Tai_label.Create(fieldtable));
  4244. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(fieldcount));
  4245. {$ifdef cpurequiresproperalignment}
  4246. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4247. {$endif cpurequiresproperalignment}
  4248. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(classtable));
  4249. symtable.foreach(@writefields,nil);
  4250. { generate the class table }
  4251. current_asmdata.asmlists[al_rtti].concat(tai_align.create(const_align(sizeof(aint))));
  4252. current_asmdata.asmlists[al_rtti].concat(Tai_label.Create(classtable));
  4253. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(proptablelist.count));
  4254. {$ifdef cpurequiresproperalignment}
  4255. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4256. {$endif cpurequiresproperalignment}
  4257. hp:=tproptablelistitem(proptablelist.first);
  4258. while assigned(hp) do
  4259. begin
  4260. current_asmdata.asmlists[al_rtti].concat(Tai_const.Createname(tobjectdef(hp.def).vmt_mangledname,0));
  4261. hp:=tproptablelistitem(hp.next);
  4262. end;
  4263. generate_field_table:=fieldtable;
  4264. proptablelist.free;
  4265. proptablelist:=nil;
  4266. end;
  4267. procedure tobjectdef.write_rtti_data(rt:trttitype);
  4268. procedure collect_unique_published_props(pd:tobjectdef);
  4269. begin
  4270. if assigned(pd.childof) then
  4271. collect_unique_published_props(pd.childof);
  4272. pd.symtable.foreach(@collect_published_properties,nil);
  4273. end;
  4274. var
  4275. i : longint;
  4276. propcount : longint;
  4277. begin
  4278. case objecttype of
  4279. odt_class:
  4280. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkclass));
  4281. odt_object:
  4282. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkobject));
  4283. odt_interfacecom:
  4284. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterface));
  4285. odt_interfacecorba:
  4286. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4287. else
  4288. exit;
  4289. end;
  4290. { generate the name }
  4291. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(objrealname^)));
  4292. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(objrealname^));
  4293. {$ifdef cpurequiresproperalignment}
  4294. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4295. {$endif cpurequiresproperalignment}
  4296. case rt of
  4297. initrtti :
  4298. begin
  4299. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(size));
  4300. if objecttype in [odt_class,odt_object] then
  4301. begin
  4302. count:=0;
  4303. FRTTIType:=rt;
  4304. symtable.foreach(@count_field_rtti,nil);
  4305. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(count));
  4306. symtable.foreach(@write_field_rtti,nil);
  4307. end;
  4308. end;
  4309. fullrtti :
  4310. begin
  4311. { Collect unique property names with nameindex }
  4312. propnamelist:=TLinkedList.Create;
  4313. collect_unique_published_props(self);
  4314. if not(objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4315. begin
  4316. if (oo_has_vmt in objectoptions) then
  4317. current_asmdata.asmlists[al_rtti].concat(Tai_const.Createname(vmt_mangledname,0))
  4318. else
  4319. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  4320. end;
  4321. { write parent typeinfo }
  4322. if assigned(childof) and ((oo_can_have_published in childof.objectoptions) or
  4323. (objecttype in [odt_interfacecom,odt_interfacecorba])) then
  4324. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_sym(childof.get_rtti_label(fullrtti)))
  4325. else
  4326. current_asmdata.asmlists[al_rtti].concat(Tai_const.create_sym(nil));
  4327. if objecttype in [odt_object,odt_class] then
  4328. begin
  4329. { total number of unique properties }
  4330. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propnamelist.count));
  4331. end
  4332. else
  4333. { interface: write flags, iid and iidstr }
  4334. begin
  4335. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(
  4336. { ugly, but working }
  4337. longint([
  4338. TCompilerIntfFlag(ord(ifHasGuid)*ord(assigned(iidguid))),
  4339. TCompilerIntfFlag(ord(ifHasStrGUID)*ord(assigned(iidstr)))
  4340. ])
  4341. {
  4342. ifDispInterface,
  4343. ifDispatch, }
  4344. ));
  4345. {$ifdef cpurequiresproperalignment}
  4346. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4347. {$endif cpurequiresproperalignment}
  4348. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_32bit(longint(iidguid^.D1)));
  4349. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(iidguid^.D2));
  4350. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(iidguid^.D3));
  4351. for i:=Low(iidguid^.D4) to High(iidguid^.D4) do
  4352. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(iidguid^.D4[i]));
  4353. end;
  4354. { write unit name }
  4355. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4356. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(current_module.realmodulename^));
  4357. {$ifdef cpurequiresproperalignment}
  4358. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4359. {$endif cpurequiresproperalignment}
  4360. { write iidstr }
  4361. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4362. begin
  4363. if assigned(iidstr) then
  4364. begin
  4365. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(length(iidstr^)));
  4366. current_asmdata.asmlists[al_rtti].concat(Tai_string.Create(iidstr^));
  4367. end
  4368. else
  4369. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0));
  4370. {$ifdef cpurequiresproperalignment}
  4371. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4372. {$endif cpurequiresproperalignment}
  4373. end;
  4374. { write published properties for this object }
  4375. if objecttype in [odt_object,odt_class] then
  4376. begin
  4377. propcount:=0;
  4378. symtable.foreach(@count_published_properties,@propcount);
  4379. current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_16bit(propcount));
  4380. {$ifdef cpurequiresproperalignment}
  4381. current_asmdata.asmlists[al_rtti].concat(Tai_align.Create(sizeof(TConstPtrUInt)));
  4382. {$endif cpurequiresproperalignment}
  4383. end;
  4384. symtable.foreach(@write_property_info,nil);
  4385. propnamelist.free;
  4386. propnamelist:=nil;
  4387. end;
  4388. end;
  4389. end;
  4390. function tobjectdef.is_publishable : boolean;
  4391. begin
  4392. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4393. end;
  4394. {****************************************************************************
  4395. TIMPLEMENTEDINTERFACES
  4396. ****************************************************************************}
  4397. type
  4398. tnamemap = class(TNamedIndexItem)
  4399. listnext : TNamedIndexItem;
  4400. newname: pstring;
  4401. constructor create(const aname, anewname: string);
  4402. destructor destroy; override;
  4403. end;
  4404. constructor tnamemap.create(const aname, anewname: string);
  4405. begin
  4406. inherited createname(aname);
  4407. newname:=stringdup(anewname);
  4408. end;
  4409. destructor tnamemap.destroy;
  4410. begin
  4411. stringdispose(newname);
  4412. inherited destroy;
  4413. end;
  4414. type
  4415. tprocdefstore = class(TNamedIndexItem)
  4416. procdef: tprocdef;
  4417. constructor create(aprocdef: tprocdef);
  4418. end;
  4419. constructor tprocdefstore.create(aprocdef: tprocdef);
  4420. begin
  4421. inherited create;
  4422. procdef:=aprocdef;
  4423. end;
  4424. constructor timplintfentry.create(aintf: tobjectdef);
  4425. begin
  4426. inherited create;
  4427. intf:=aintf;
  4428. ioffset:=-1;
  4429. namemappings:=nil;
  4430. procdefs:=nil;
  4431. end;
  4432. constructor timplintfentry.create_deref(const d:tderef);
  4433. begin
  4434. inherited create;
  4435. intf:=nil;
  4436. intfderef:=d;
  4437. ioffset:=-1;
  4438. namemappings:=nil;
  4439. procdefs:=nil;
  4440. end;
  4441. destructor timplintfentry.destroy;
  4442. begin
  4443. if assigned(namemappings) then
  4444. namemappings.free;
  4445. if assigned(procdefs) then
  4446. procdefs.free;
  4447. inherited destroy;
  4448. end;
  4449. constructor timplementedinterfaces.create;
  4450. begin
  4451. finterfaces:=tindexarray.create(1);
  4452. end;
  4453. destructor timplementedinterfaces.destroy;
  4454. begin
  4455. finterfaces.destroy;
  4456. end;
  4457. function timplementedinterfaces.count: longint;
  4458. begin
  4459. count:=finterfaces.count;
  4460. end;
  4461. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4462. begin
  4463. if (intfindex<1) or (intfindex>count) then
  4464. InternalError(200006123);
  4465. end;
  4466. function timplementedinterfaces.interfaces(intfindex: longint): tobjectdef;
  4467. begin
  4468. checkindex(intfindex);
  4469. interfaces:=timplintfentry(finterfaces.search(intfindex)).intf;
  4470. end;
  4471. function timplementedinterfaces.interfacesderef(intfindex: longint): tderef;
  4472. begin
  4473. checkindex(intfindex);
  4474. interfacesderef:=timplintfentry(finterfaces.search(intfindex)).intfderef;
  4475. end;
  4476. function timplementedinterfaces.ioffsets(intfindex: longint): longint;
  4477. begin
  4478. checkindex(intfindex);
  4479. ioffsets:=timplintfentry(finterfaces.search(intfindex)).ioffset;
  4480. end;
  4481. procedure timplementedinterfaces.setioffsets(intfindex,iofs:longint);
  4482. begin
  4483. checkindex(intfindex);
  4484. timplintfentry(finterfaces.search(intfindex)).ioffset:=iofs;
  4485. end;
  4486. function timplementedinterfaces.implindex(intfindex:longint):longint;
  4487. begin
  4488. checkindex(intfindex);
  4489. result:=timplintfentry(finterfaces.search(intfindex)).implindex;
  4490. end;
  4491. procedure timplementedinterfaces.setimplindex(intfindex,implidx:longint);
  4492. begin
  4493. checkindex(intfindex);
  4494. timplintfentry(finterfaces.search(intfindex)).implindex:=implidx;
  4495. end;
  4496. function timplementedinterfaces.searchintf(def: tdef): longint;
  4497. var
  4498. i: longint;
  4499. begin
  4500. i:=1;
  4501. while (i<=count) and (tdef(interfaces(i))<>def) do inc(i);
  4502. if i<=count then
  4503. searchintf:=i
  4504. else
  4505. searchintf:=-1;
  4506. end;
  4507. procedure timplementedinterfaces.buildderef;
  4508. var
  4509. i: longint;
  4510. begin
  4511. for i:=1 to count do
  4512. with timplintfentry(finterfaces.search(i)) do
  4513. intfderef.build(intf);
  4514. end;
  4515. procedure timplementedinterfaces.deref;
  4516. var
  4517. i: longint;
  4518. begin
  4519. for i:=1 to count do
  4520. with timplintfentry(finterfaces.search(i)) do
  4521. intf:=tobjectdef(intfderef.resolve);
  4522. end;
  4523. procedure timplementedinterfaces.addintf_deref(const d:tderef;iofs:longint);
  4524. var
  4525. hintf : timplintfentry;
  4526. begin
  4527. hintf:=timplintfentry.create_deref(d);
  4528. hintf.ioffset:=iofs;
  4529. finterfaces.insert(hintf);
  4530. end;
  4531. procedure timplementedinterfaces.addintf_ioffset(d:tdef;iofs:longint);
  4532. var
  4533. hintf : timplintfentry;
  4534. begin
  4535. hintf:=timplintfentry.create(tobjectdef(d));
  4536. hintf.ioffset:=iofs;
  4537. finterfaces.insert(hintf);
  4538. end;
  4539. procedure timplementedinterfaces.addintf(def: tdef);
  4540. begin
  4541. if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or
  4542. not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4543. internalerror(200006124);
  4544. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4545. end;
  4546. procedure timplementedinterfaces.clearmappings;
  4547. var
  4548. i: longint;
  4549. begin
  4550. for i:=1 to count do
  4551. with timplintfentry(finterfaces.search(i)) do
  4552. begin
  4553. if assigned(namemappings) then
  4554. namemappings.free;
  4555. namemappings:=nil;
  4556. end;
  4557. end;
  4558. procedure timplementedinterfaces.addmappings(intfindex: longint; const origname, newname: string);
  4559. begin
  4560. checkindex(intfindex);
  4561. with timplintfentry(finterfaces.search(intfindex)) do
  4562. begin
  4563. if not assigned(namemappings) then
  4564. namemappings:=tdictionary.create;
  4565. namemappings.insert(tnamemap.create(origname,newname));
  4566. end;
  4567. end;
  4568. function timplementedinterfaces.getmappings(intfindex: longint; const origname: string; var nextexist: pointer): string;
  4569. begin
  4570. checkindex(intfindex);
  4571. if not assigned(nextexist) then
  4572. with timplintfentry(finterfaces.search(intfindex)) do
  4573. begin
  4574. if assigned(namemappings) then
  4575. nextexist:=namemappings.search(origname)
  4576. else
  4577. nextexist:=nil;
  4578. end;
  4579. if assigned(nextexist) then
  4580. begin
  4581. getmappings:=tnamemap(nextexist).newname^;
  4582. nextexist:=tnamemap(nextexist).listnext;
  4583. end
  4584. else
  4585. getmappings:='';
  4586. end;
  4587. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef);
  4588. var
  4589. found : boolean;
  4590. i : longint;
  4591. begin
  4592. checkindex(intfindex);
  4593. with timplintfentry(finterfaces.search(intfindex)) do
  4594. begin
  4595. if not assigned(procdefs) then
  4596. procdefs:=tindexarray.create(4);
  4597. { No duplicate entries of the same procdef }
  4598. found:=false;
  4599. for i:=1 to procdefs.count do
  4600. if tprocdefstore(procdefs.search(i)).procdef=procdef then
  4601. begin
  4602. found:=true;
  4603. break;
  4604. end;
  4605. if not found then
  4606. procdefs.insert(tprocdefstore.create(procdef));
  4607. end;
  4608. end;
  4609. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4610. begin
  4611. checkindex(intfindex);
  4612. with timplintfentry(finterfaces.search(intfindex)) do
  4613. if assigned(procdefs) then
  4614. implproccount:=procdefs.count
  4615. else
  4616. implproccount:=0;
  4617. end;
  4618. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef;
  4619. begin
  4620. checkindex(intfindex);
  4621. with timplintfentry(finterfaces.search(intfindex)) do
  4622. if assigned(procdefs) then
  4623. implprocs:=tprocdefstore(procdefs.search(procindex)).procdef
  4624. else
  4625. internalerror(200006131);
  4626. end;
  4627. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4628. var
  4629. possible: boolean;
  4630. i: longint;
  4631. iiep1: TIndexArray;
  4632. iiep2: TIndexArray;
  4633. begin
  4634. checkindex(intfindex);
  4635. checkindex(remainindex);
  4636. iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs;
  4637. iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs;
  4638. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4639. begin
  4640. possible:=true;
  4641. weight:=0;
  4642. end
  4643. else
  4644. begin
  4645. possible:=assigned(iiep2) and (iiep1.count<=iiep2.count);
  4646. i:=1;
  4647. while (possible) and (i<=iiep1.count) do
  4648. begin
  4649. possible:=
  4650. (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef);
  4651. inc(i);
  4652. end;
  4653. if possible then
  4654. weight:=iiep1.count;
  4655. end;
  4656. isimplmergepossible:=possible;
  4657. end;
  4658. {****************************************************************************
  4659. TFORWARDDEF
  4660. ****************************************************************************}
  4661. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  4662. begin
  4663. inherited create(forwarddef);
  4664. tosymname:=stringdup(s);
  4665. forwardpos:=pos;
  4666. end;
  4667. function tforwarddef.gettypename:string;
  4668. begin
  4669. gettypename:='unresolved forward to '+tosymname^;
  4670. end;
  4671. destructor tforwarddef.destroy;
  4672. begin
  4673. if assigned(tosymname) then
  4674. stringdispose(tosymname);
  4675. inherited destroy;
  4676. end;
  4677. {****************************************************************************
  4678. TUNDEFINEDDEF
  4679. ****************************************************************************}
  4680. constructor tundefineddef.create;
  4681. begin
  4682. inherited create(undefineddef);
  4683. end;
  4684. constructor tundefineddef.ppuload(ppufile:tcompilerppufile);
  4685. begin
  4686. inherited ppuload(undefineddef,ppufile);
  4687. end;
  4688. function tundefineddef.gettypename:string;
  4689. begin
  4690. gettypename:='<undefined type>';
  4691. end;
  4692. procedure tundefineddef.ppuwrite(ppufile:tcompilerppufile);
  4693. begin
  4694. inherited ppuwrite(ppufile);
  4695. ppufile.writeentry(ibundefineddef);
  4696. end;
  4697. {****************************************************************************
  4698. TERRORDEF
  4699. ****************************************************************************}
  4700. constructor terrordef.create;
  4701. begin
  4702. inherited create(errordef);
  4703. end;
  4704. procedure terrordef.ppuwrite(ppufile:tcompilerppufile);
  4705. begin
  4706. { Can't write errordefs to ppu }
  4707. internalerror(200411063);
  4708. end;
  4709. function terrordef.gettypename:string;
  4710. begin
  4711. gettypename:='<erroneous type>';
  4712. end;
  4713. function terrordef.getmangledparaname:string;
  4714. begin
  4715. getmangledparaname:='error';
  4716. end;
  4717. {****************************************************************************
  4718. Definition Helpers
  4719. ****************************************************************************}
  4720. function is_interfacecom(def: tdef): boolean;
  4721. begin
  4722. is_interfacecom:=
  4723. assigned(def) and
  4724. (def.deftype=objectdef) and
  4725. (tobjectdef(def).objecttype=odt_interfacecom);
  4726. end;
  4727. function is_interfacecorba(def: tdef): boolean;
  4728. begin
  4729. is_interfacecorba:=
  4730. assigned(def) and
  4731. (def.deftype=objectdef) and
  4732. (tobjectdef(def).objecttype=odt_interfacecorba);
  4733. end;
  4734. function is_interface(def: tdef): boolean;
  4735. begin
  4736. is_interface:=
  4737. assigned(def) and
  4738. (def.deftype=objectdef) and
  4739. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  4740. end;
  4741. function is_dispinterface(def: tdef): boolean;
  4742. begin
  4743. result:=
  4744. assigned(def) and
  4745. (def.deftype=objectdef) and
  4746. (tobjectdef(def).objecttype=odt_dispinterface);
  4747. end;
  4748. function is_class(def: tdef): boolean;
  4749. begin
  4750. is_class:=
  4751. assigned(def) and
  4752. (def.deftype=objectdef) and
  4753. (tobjectdef(def).objecttype=odt_class);
  4754. end;
  4755. function is_object(def: tdef): boolean;
  4756. begin
  4757. is_object:=
  4758. assigned(def) and
  4759. (def.deftype=objectdef) and
  4760. (tobjectdef(def).objecttype=odt_object);
  4761. end;
  4762. function is_cppclass(def: tdef): boolean;
  4763. begin
  4764. is_cppclass:=
  4765. assigned(def) and
  4766. (def.deftype=objectdef) and
  4767. (tobjectdef(def).objecttype=odt_cppclass);
  4768. end;
  4769. function is_class_or_interface(def: tdef): boolean;
  4770. begin
  4771. is_class_or_interface:=
  4772. assigned(def) and
  4773. (def.deftype=objectdef) and
  4774. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4775. end;
  4776. function is_class_or_interface_or_dispinterface(def: tdef): boolean;
  4777. begin
  4778. result:=
  4779. assigned(def) and
  4780. (def.deftype=objectdef) and
  4781. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba,odt_dispinterface]);
  4782. end;
  4783. {$ifdef x86}
  4784. function use_sse(def : tdef) : boolean;
  4785. begin
  4786. use_sse:=(is_single(def) and (aktfputype in sse_singlescalar)) or
  4787. (is_double(def) and (aktfputype in sse_doublescalar));
  4788. end;
  4789. {$endif x86}
  4790. end.