symdef.pas 202 KB

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