symdef.pas 192 KB

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