symdef.pas 191 KB

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