symdef.pas 203 KB

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