symdef.pas 169 KB

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