symdef.pas 177 KB

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