symdef.pas 175 KB

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