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