symdef.pas 194 KB

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