symdef.pas 198 KB

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