symdef.pas 203 KB

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