symdef.pas 199 KB

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