symdef.pas 194 KB

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