symdef.pas 170 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710
  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. { assign TGUID? }
  2490. if not(assigned(rec_tguid)) and
  2491. (upper(typename)='TGUID') and
  2492. assigned(owner) and
  2493. (owner^.name^='SYSTEM') then
  2494. rec_tguid:=@self;
  2495. end;
  2496. procedure trecorddef.write;
  2497. var
  2498. oldread_member : boolean;
  2499. begin
  2500. oldread_member:=read_member;
  2501. read_member:=true;
  2502. inherited write;
  2503. writelong(savesize);
  2504. current_ppu^.writeentry(ibrecorddef);
  2505. pstoredsymtable(symtable)^.writeas;
  2506. read_member:=oldread_member;
  2507. end;
  2508. function trecorddef.size:longint;
  2509. begin
  2510. size:=symtable^.datasize;
  2511. end;
  2512. function trecorddef.alignment:longint;
  2513. var
  2514. l : longint;
  2515. hp : pvarsym;
  2516. begin
  2517. { also check the first symbol for it's size, because a
  2518. packed record has dataalignment of 1, but the first
  2519. sym could be a longint which should be aligned on 4 bytes,
  2520. this is compatible with C record packing (PFV) }
  2521. hp:=pvarsym(symtable^.symindex^.first);
  2522. if assigned(hp) then
  2523. begin
  2524. if hp^.vartype.def^.deftype in [recorddef,arraydef] then
  2525. l:=hp^.vartype.def^.alignment
  2526. else
  2527. l:=hp^.vartype.def^.size;
  2528. if l>symtable^.dataalignment then
  2529. begin
  2530. if l>=4 then
  2531. alignment:=4
  2532. else
  2533. if l>=2 then
  2534. alignment:=2
  2535. else
  2536. alignment:=1;
  2537. end
  2538. else
  2539. alignment:=symtable^.dataalignment;
  2540. end
  2541. else
  2542. alignment:=symtable^.dataalignment;
  2543. end;
  2544. {$ifdef GDB}
  2545. Const StabRecString : pchar = Nil;
  2546. StabRecSize : longint = 0;
  2547. RecOffset : Longint = 0;
  2548. procedure addname(p : pnamedindexobject);
  2549. var
  2550. news, newrec : pchar;
  2551. spec : string[3];
  2552. size : longint;
  2553. begin
  2554. { static variables from objects are like global objects }
  2555. if (sp_static in psym(p)^.symoptions) then
  2556. exit;
  2557. If psym(p)^.typ = varsym then
  2558. begin
  2559. if (sp_protected in psym(p)^.symoptions) then
  2560. spec:='/1'
  2561. else if (sp_private in psym(p)^.symoptions) then
  2562. spec:='/0'
  2563. else
  2564. spec:='';
  2565. if not assigned(pvarsym(p)^.vartype.def) then
  2566. writeln(pvarsym(p)^.name);
  2567. { class fields are pointers PM, obsolete now PM }
  2568. {if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
  2569. pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
  2570. spec:=spec+'*'; }
  2571. size:=pvarsym(p)^.vartype.def^.size;
  2572. { open arrays made overflows !! }
  2573. if size>$fffffff then
  2574. size:=$fffffff;
  2575. newrec := strpnew(p^.name+':'+spec+pstoreddef(pvarsym(p)^.vartype.def)^.numberstring
  2576. +','+tostr(pvarsym(p)^.address*8)+','
  2577. +tostr(size*8)+';');
  2578. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2579. begin
  2580. getmem(news,stabrecsize+memsizeinc);
  2581. strcopy(news,stabrecstring);
  2582. freemem(stabrecstring,stabrecsize);
  2583. stabrecsize:=stabrecsize+memsizeinc;
  2584. stabrecstring:=news;
  2585. end;
  2586. strcat(StabRecstring,newrec);
  2587. strdispose(newrec);
  2588. {This should be used for case !!}
  2589. RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;
  2590. end;
  2591. end;
  2592. function trecorddef.stabstring : pchar;
  2593. Var oldrec : pchar;
  2594. oldsize,oldrecoffset : longint;
  2595. begin
  2596. oldrec := stabrecstring;
  2597. oldsize:=stabrecsize;
  2598. GetMem(stabrecstring,memsizeinc);
  2599. stabrecsize:=memsizeinc;
  2600. strpcopy(stabRecString,'s'+tostr(size));
  2601. OldRecOffset:=RecOffset;
  2602. RecOffset := 0;
  2603. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  2604. strpcopy(strend(StabRecString),';');
  2605. stabstring := strnew(StabRecString);
  2606. Freemem(stabrecstring,stabrecsize);
  2607. stabrecstring := oldrec;
  2608. stabrecsize:=oldsize;
  2609. RecOffset:=OldRecOffset;
  2610. end;
  2611. procedure trecorddef.concatstabto(asmlist : taasmoutput);
  2612. begin
  2613. if (not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2614. (is_def_stab_written = not_written) then
  2615. inherited concatstabto(asmlist);
  2616. end;
  2617. {$endif GDB}
  2618. var
  2619. count : longint;
  2620. procedure count_inittable_fields(sym : pnamedindexobject);
  2621. begin
  2622. if ((psym(sym)^.typ=varsym) and
  2623. pvarsym(sym)^.vartype.def^.needs_inittable) {and
  2624. (pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  2625. not(is_class(pdef(pvarsym(sym)^.vartype.def)))} then
  2626. inc(count);
  2627. end;
  2628. procedure count_fields(sym : pnamedindexobject);
  2629. begin
  2630. inc(count);
  2631. end;
  2632. procedure write_field_inittable(sym : pnamedindexobject);
  2633. begin
  2634. if ((psym(sym)^.typ=varsym) and
  2635. pvarsym(sym)^.vartype.def^.needs_inittable) and
  2636. ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  2637. not(is_class(pvarsym(sym)^.vartype.def))) then
  2638. begin
  2639. rttiList.concat(Tai_const_symbol.Create(pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label));
  2640. rttiList.concat(Tai_const.Create_32bit(pvarsym(sym)^.address));
  2641. end;
  2642. end;
  2643. procedure write_field_rtti(sym : pnamedindexobject);
  2644. begin
  2645. rttiList.concat(Tai_const_symbol.Createname(pvarsym(sym)^.vartype.def^.get_rtti_label));
  2646. rttiList.concat(Tai_const.Create_32bit(pvarsym(sym)^.address));
  2647. end;
  2648. procedure generate_child_inittable(sym:pnamedindexobject);
  2649. begin
  2650. if (psym(sym)^.typ=varsym) and
  2651. pvarsym(sym)^.vartype.def^.needs_inittable then
  2652. { force inittable generation }
  2653. pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label;
  2654. end;
  2655. procedure generate_child_rtti(sym : pnamedindexobject);
  2656. begin
  2657. pvarsym(sym)^.vartype.def^.get_rtti_label;
  2658. end;
  2659. procedure trecorddef.write_child_rtti_data;
  2660. begin
  2661. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_rtti);
  2662. end;
  2663. procedure trecorddef.write_child_init_data;
  2664. begin
  2665. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  2666. end;
  2667. procedure trecorddef.write_rtti_data;
  2668. begin
  2669. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2670. write_rtti_name;
  2671. rttiList.concat(Tai_const.Create_32bit(size));
  2672. count:=0;
  2673. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_fields);
  2674. rttiList.concat(Tai_const.Create_32bit(count));
  2675. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
  2676. end;
  2677. procedure trecorddef.write_init_data;
  2678. begin
  2679. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2680. write_rtti_name;
  2681. rttiList.concat(Tai_const.Create_32bit(size));
  2682. count:=0;
  2683. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  2684. rttiList.concat(Tai_const.Create_32bit(count));
  2685. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  2686. end;
  2687. function trecorddef.gettypename : string;
  2688. begin
  2689. gettypename:='<record type>'
  2690. end;
  2691. {***************************************************************************
  2692. TABSTRACTPROCDEF
  2693. ***************************************************************************}
  2694. constructor tabstractprocdef.init;
  2695. begin
  2696. inherited init;
  2697. para:=TParaLinkedList.Create;
  2698. minparacount:=0;
  2699. maxparacount:=0;
  2700. fpu_used:=0;
  2701. proctypeoption:=potype_none;
  2702. proccalloptions:=[];
  2703. procoptions:=[];
  2704. rettype.setdef(voiddef);
  2705. symtablelevel:=0;
  2706. savesize:=target_os.size_of_pointer;
  2707. end;
  2708. destructor tabstractprocdef.done;
  2709. begin
  2710. Para.Free;
  2711. inherited done;
  2712. end;
  2713. procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez;defval:psym);
  2714. var
  2715. hp : TParaItem;
  2716. begin
  2717. hp:=TParaItem.Create;
  2718. hp.paratyp:=vsp;
  2719. hp.paratype:=tt;
  2720. hp.register:=R_NO;
  2721. hp.defaultvalue:=defval;
  2722. Para.insert(hp);
  2723. if not assigned(defval) then
  2724. inc(minparacount);
  2725. inc(maxparacount);
  2726. end;
  2727. { all functions returning in FPU are
  2728. assume to use 2 FPU registers
  2729. until the function implementation
  2730. is processed PM }
  2731. procedure tabstractprocdef.test_if_fpu_result;
  2732. begin
  2733. if assigned(rettype.def) and
  2734. (rettype.def^.deftype=floatdef) and
  2735. (pfloatdef(rettype.def)^.typ<>f32bit) then
  2736. fpu_used:=2;
  2737. end;
  2738. procedure tabstractprocdef.deref;
  2739. var
  2740. hp : TParaItem;
  2741. begin
  2742. inherited deref;
  2743. rettype.resolve;
  2744. hp:=TParaItem(Para.first);
  2745. while assigned(hp) do
  2746. begin
  2747. hp.paratype.resolve;
  2748. resolvesym(psym(hp.defaultvalue));
  2749. hp:=TParaItem(hp.next);
  2750. end;
  2751. end;
  2752. constructor tabstractprocdef.load;
  2753. var
  2754. hp : TParaItem;
  2755. count,i : word;
  2756. begin
  2757. inherited load;
  2758. Para:=TParaLinkedList.Create;
  2759. minparacount:=0;
  2760. maxparacount:=0;
  2761. rettype.load;
  2762. fpu_used:=readbyte;
  2763. proctypeoption:=tproctypeoption(readlong);
  2764. readsmallset(proccalloptions);
  2765. readsmallset(procoptions);
  2766. count:=readword;
  2767. savesize:=target_os.size_of_pointer;
  2768. for i:=1 to count do
  2769. begin
  2770. hp:=TParaItem.Create;
  2771. hp.paratyp:=tvarspez(readbyte);
  2772. { hp.register:=tregister(readbyte); }
  2773. hp.register:=R_NO;
  2774. hp.paratype.load;
  2775. hp.defaultvalue:=psym(readderef);
  2776. if not assigned(hp.defaultvalue) then
  2777. inc(minparacount);
  2778. inc(maxparacount);
  2779. Para.concat(hp);
  2780. end;
  2781. end;
  2782. procedure tabstractprocdef.write;
  2783. var
  2784. hp : TParaItem;
  2785. oldintfcrc : boolean;
  2786. begin
  2787. inherited write;
  2788. rettype.write;
  2789. oldintfcrc:=current_ppu^.do_interface_crc;
  2790. current_ppu^.do_interface_crc:=false;
  2791. writebyte(fpu_used);
  2792. writelong(ord(proctypeoption));
  2793. writesmallset(proccalloptions);
  2794. writesmallset(procoptions);
  2795. current_ppu^.do_interface_crc:=oldintfcrc;
  2796. writeword(maxparacount);
  2797. hp:=TParaItem(Para.first);
  2798. while assigned(hp) do
  2799. begin
  2800. writebyte(byte(hp.paratyp));
  2801. { writebyte(byte(hp.register)); }
  2802. hp.paratype.write;
  2803. writederef(hp.defaultvalue);
  2804. hp:=TParaItem(hp.next);
  2805. end;
  2806. end;
  2807. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2808. var
  2809. pdc : TParaItem;
  2810. l : longint;
  2811. begin
  2812. l:=0;
  2813. pdc:=TParaItem(Para.first);
  2814. while assigned(pdc) do
  2815. begin
  2816. case pdc.paratyp of
  2817. vs_out,
  2818. vs_var : inc(l,target_os.size_of_pointer);
  2819. vs_value,
  2820. vs_const : if push_addr_param(pdc.paratype.def) then
  2821. inc(l,target_os.size_of_pointer)
  2822. else
  2823. inc(l,pdc.paratype.def^.size);
  2824. end;
  2825. l:=align(l,alignsize);
  2826. pdc:=TParaItem(pdc.next);
  2827. end;
  2828. para_size:=l;
  2829. end;
  2830. function tabstractprocdef.demangled_paras : string;
  2831. var
  2832. hs,s : string;
  2833. hp : TParaItem;
  2834. hpc : pconstsym;
  2835. begin
  2836. hp:=TParaItem(Para.last);
  2837. if not(assigned(hp)) then
  2838. begin
  2839. demangled_paras:='';
  2840. exit;
  2841. end;
  2842. s:='(';
  2843. while assigned(hp) do
  2844. begin
  2845. if assigned(hp.paratype.def^.typesym) then
  2846. s:=s+hp.paratype.def^.typesym^.realname
  2847. else if hp.paratyp=vs_var then
  2848. s:=s+'var'
  2849. else if hp.paratyp=vs_const then
  2850. s:=s+'const'
  2851. else if hp.paratyp=vs_out then
  2852. s:=s+'out';
  2853. { default value }
  2854. if assigned(hp.defaultvalue) then
  2855. begin
  2856. hpc:=pconstsym(hp.defaultvalue);
  2857. hs:='';
  2858. case hpc^.consttyp of
  2859. conststring,
  2860. constresourcestring :
  2861. hs:=strpas(pchar(tpointerord(hpc^.value)));
  2862. constreal :
  2863. str(pbestreal(tpointerord(hpc^.value))^,hs);
  2864. constord,
  2865. constpointer :
  2866. hs:=tostr(hpc^.value);
  2867. constbool :
  2868. begin
  2869. if hpc^.value<>0 then
  2870. hs:='TRUE'
  2871. else
  2872. hs:='FALSE';
  2873. end;
  2874. constnil :
  2875. hs:='nil';
  2876. constchar :
  2877. hs:=chr(hpc^.value);
  2878. constset :
  2879. hs:='<set>';
  2880. end;
  2881. if hs<>'' then
  2882. s:=s+'="'+hs+'"';
  2883. end;
  2884. hp:=TParaItem(hp.previous);
  2885. if assigned(hp) then
  2886. s:=s+',';
  2887. end;
  2888. s:=s+')';
  2889. demangled_paras:=s;
  2890. end;
  2891. function tabstractprocdef.proccalloption2str : string;
  2892. type
  2893. tproccallopt=record
  2894. mask : tproccalloption;
  2895. str : string[30];
  2896. end;
  2897. const
  2898. proccallopts=13;
  2899. proccallopt : array[1..proccallopts] of tproccallopt=(
  2900. (mask:pocall_none; str:''),
  2901. (mask:pocall_clearstack; str:'ClearStack'),
  2902. (mask:pocall_leftright; str:'LeftRight'),
  2903. (mask:pocall_cdecl; str:'CDecl'),
  2904. (mask:pocall_register; str:'Register'),
  2905. (mask:pocall_stdcall; str:'StdCall'),
  2906. (mask:pocall_safecall; str:'SafeCall'),
  2907. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2908. (mask:pocall_system; str:'System'),
  2909. (mask:pocall_inline; str:'Inline'),
  2910. (mask:pocall_internproc; str:'InternProc'),
  2911. (mask:pocall_internconst; str:'InternConst'),
  2912. (mask:pocall_cdecl; str:'CPPDecl')
  2913. );
  2914. var
  2915. s : string;
  2916. i : longint;
  2917. first : boolean;
  2918. begin
  2919. s:='';
  2920. first:=true;
  2921. for i:=1to proccallopts do
  2922. if (proccallopt[i].mask in proccalloptions) then
  2923. begin
  2924. if first then
  2925. first:=false
  2926. else
  2927. s:=s+';';
  2928. s:=s+proccallopt[i].str;
  2929. end;
  2930. proccalloption2str:=s;
  2931. end;
  2932. {$ifdef GDB}
  2933. function tabstractprocdef.stabstring : pchar;
  2934. begin
  2935. stabstring := strpnew('abstractproc'+numberstring+';');
  2936. end;
  2937. procedure tabstractprocdef.concatstabto(asmlist : taasmoutput);
  2938. begin
  2939. if (not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2940. and (is_def_stab_written = not_written) then
  2941. begin
  2942. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2943. inherited concatstabto(asmlist);
  2944. end;
  2945. end;
  2946. {$endif GDB}
  2947. {***************************************************************************
  2948. TPROCDEF
  2949. ***************************************************************************}
  2950. constructor tprocdef.init;
  2951. begin
  2952. inherited init;
  2953. deftype:=procdef;
  2954. _mangledname:=nil;
  2955. nextoverloaded:=nil;
  2956. fileinfo:=aktfilepos;
  2957. extnumber:=-1;
  2958. aliasnames:=tstringlist.create;
  2959. localst:=new(pstoredsymtable,init(localsymtable));
  2960. parast:=new(pstoredsymtable,init(parasymtable));
  2961. localst^.defowner:=@self;
  2962. parast^.defowner:=@self;
  2963. { this is used by insert
  2964. to check same names in parast and localst }
  2965. localst^.next:=parast;
  2966. defref:=nil;
  2967. crossref:=nil;
  2968. lastwritten:=nil;
  2969. refcount:=0;
  2970. if (cs_browser in aktmoduleswitches) and make_ref then
  2971. begin
  2972. defref:=new(pref,init(defref,@akttokenpos));
  2973. inc(refcount);
  2974. end;
  2975. lastref:=defref;
  2976. { first, we assume that all registers are used }
  2977. {$ifdef newcg}
  2978. usedregisters:=[firstreg..lastreg];
  2979. {$else newcg}
  2980. {$ifdef i386}
  2981. usedregisters:=$ff;
  2982. {$endif i386}
  2983. {$ifdef m68k}
  2984. usedregisters:=$FFFF;
  2985. {$endif}
  2986. {$endif newcg}
  2987. forwarddef:=true;
  2988. interfacedef:=false;
  2989. hasforward:=false;
  2990. _class := nil;
  2991. code:=nil;
  2992. regvarinfo := nil;
  2993. count:=false;
  2994. is_used:=false;
  2995. end;
  2996. constructor tprocdef.load;
  2997. begin
  2998. inherited load;
  2999. deftype:=procdef;
  3000. {$ifdef newcg}
  3001. readnormalset(usedregisters);
  3002. {$else newcg}
  3003. {$ifdef i386}
  3004. usedregisters:=readbyte;
  3005. {$endif i386}
  3006. {$ifdef m68k}
  3007. usedregisters:=readword;
  3008. {$endif}
  3009. {$endif newcg}
  3010. _mangledname:=stringdup(readstring);
  3011. extnumber:=readlong;
  3012. nextoverloaded:=pprocdef(readderef);
  3013. _class := pobjectdef(readderef);
  3014. readposinfo(fileinfo);
  3015. if (cs_link_deffile in aktglobalswitches) and
  3016. (tf_need_export in target_info.flags) and
  3017. (po_exports in procoptions) then
  3018. deffile.AddExport(mangledname);
  3019. aliasnames:=tstringlist.create;
  3020. parast:=new(pstoredsymtable,loadas(parasymtable));
  3021. parast^.defowner:=@self;
  3022. {new(localst,loadas(localsymtable));
  3023. localst^.defowner:=@self;
  3024. parast^.next:=localst;
  3025. localst^.next:=owner;}
  3026. forwarddef:=false;
  3027. interfacedef:=false;
  3028. hasforward:=false;
  3029. code := nil;
  3030. regvarinfo := nil;
  3031. lastref:=nil;
  3032. lastwritten:=nil;
  3033. defref:=nil;
  3034. refcount:=0;
  3035. count:=true;
  3036. is_used:=false;
  3037. end;
  3038. function tprocdef.fullprocname:string;
  3039. var
  3040. s : string;
  3041. begin
  3042. s:='';
  3043. if assigned(_class) then
  3044. s:=_class^.objname^+'.';
  3045. s:=s+procsym^.realname+demangled_paras;
  3046. fullprocname:=s;
  3047. end;
  3048. function tprocdef.fullprocnamewithret:string;
  3049. var
  3050. s : string;
  3051. begin
  3052. s:=fullprocname;
  3053. if assigned(rettype.def) and
  3054. not(is_equal(rettype.def,voiddef)) then
  3055. s:=s+' : '+rettype.def^.gettypename;
  3056. fullprocnamewithret:=s;
  3057. end;
  3058. function tprocdef.getsymtable(t:tgetsymtable):psymtable;
  3059. begin
  3060. case t of
  3061. gs_local :
  3062. getsymtable:=localst;
  3063. gs_para :
  3064. getsymtable:=parast;
  3065. else
  3066. getsymtable:=nil;
  3067. end;
  3068. end;
  3069. Const local_symtable_index : longint = $8001;
  3070. procedure tprocdef.load_references;
  3071. var
  3072. pos : tfileposinfo;
  3073. {$ifndef NOLOCALBROWSER}
  3074. oldsymtablestack,
  3075. st : psymtable;
  3076. {$endif ndef NOLOCALBROWSER}
  3077. move_last : boolean;
  3078. begin
  3079. move_last:=lastwritten=lastref;
  3080. while (not current_ppu^.endofentry) do
  3081. begin
  3082. readposinfo(pos);
  3083. inc(refcount);
  3084. lastref:=new(pref,init(lastref,@pos));
  3085. lastref^.is_written:=true;
  3086. if refcount=1 then
  3087. defref:=lastref;
  3088. end;
  3089. if move_last then
  3090. lastwritten:=lastref;
  3091. if ((current_module.flags and uf_local_browser)<>0)
  3092. and is_in_current then
  3093. begin
  3094. {$ifndef NOLOCALBROWSER}
  3095. oldsymtablestack:=symtablestack;
  3096. st:=aktlocalsymtable;
  3097. parast:=new(pstoredsymtable,loadas(parasymtable));
  3098. parast^.defowner:=@self;
  3099. aktlocalsymtable:=parast;
  3100. pstoredsymtable(parast)^.deref;
  3101. parast^.next:=owner;
  3102. pstoredsymtable(parast)^.load_browser;
  3103. aktlocalsymtable:=st;
  3104. localst:=new(pstoredsymtable,loadas(localsymtable));
  3105. localst^.defowner:=@self;
  3106. aktlocalsymtable:=localst;
  3107. symtablestack:=parast;
  3108. pstoredsymtable(localst)^.deref;
  3109. localst^.next:=parast;
  3110. pstoredsymtable(localst)^.load_browser;
  3111. aktlocalsymtable:=st;
  3112. symtablestack:=oldsymtablestack;
  3113. {$endif ndef NOLOCALBROWSER}
  3114. end;
  3115. end;
  3116. function tprocdef.write_references : boolean;
  3117. var
  3118. ref : pref;
  3119. {$ifndef NOLOCALBROWSER}
  3120. st : psymtable;
  3121. pdo : pobjectdef;
  3122. {$endif ndef NOLOCALBROWSER}
  3123. move_last : boolean;
  3124. begin
  3125. move_last:=lastwritten=lastref;
  3126. if move_last and (((current_module.flags and uf_local_browser)=0)
  3127. or not is_in_current) then
  3128. exit;
  3129. { write address of this symbol }
  3130. writederef(@self);
  3131. { write refs }
  3132. if assigned(lastwritten) then
  3133. ref:=lastwritten
  3134. else
  3135. ref:=defref;
  3136. while assigned(ref) do
  3137. begin
  3138. if ref^.moduleindex=current_module.unit_index then
  3139. begin
  3140. writeposinfo(ref^.posinfo);
  3141. ref^.is_written:=true;
  3142. if move_last then
  3143. lastwritten:=ref;
  3144. end
  3145. else if not ref^.is_written then
  3146. move_last:=false
  3147. else if move_last then
  3148. lastwritten:=ref;
  3149. ref:=ref^.nextref;
  3150. end;
  3151. current_ppu^.writeentry(ibdefref);
  3152. write_references:=true;
  3153. if ((current_module.flags and uf_local_browser)<>0)
  3154. and is_in_current then
  3155. begin
  3156. {$ifndef NOLOCALBROWSER}
  3157. pdo:=_class;
  3158. if (owner^.symtabletype<>localsymtable) then
  3159. while assigned(pdo) do
  3160. begin
  3161. if pdo^.symtable<>aktrecordsymtable then
  3162. begin
  3163. pdo^.symtable^.unitid:=local_symtable_index;
  3164. inc(local_symtable_index);
  3165. end;
  3166. pdo:=pdo^.childof;
  3167. end;
  3168. { we need TESTLOCALBROWSER para and local symtables
  3169. PPU files are then easier to read PM }
  3170. if not assigned(parast) then
  3171. parast:=new(pstoredsymtable,init(parasymtable));
  3172. parast^.defowner:=@self;
  3173. st:=aktlocalsymtable;
  3174. aktlocalsymtable:=parast;
  3175. pstoredsymtable(parast)^.writeas;
  3176. parast^.unitid:=local_symtable_index;
  3177. inc(local_symtable_index);
  3178. pstoredsymtable(parast)^.write_browser;
  3179. if not assigned(localst) then
  3180. localst:=new(pstoredsymtable,init(localsymtable));
  3181. localst^.defowner:=@self;
  3182. aktlocalsymtable:=localst;
  3183. pstoredsymtable(localst)^.writeas;
  3184. localst^.unitid:=local_symtable_index;
  3185. inc(local_symtable_index);
  3186. pstoredsymtable(localst)^.write_browser;
  3187. aktlocalsymtable:=st;
  3188. { decrement for }
  3189. local_symtable_index:=local_symtable_index-2;
  3190. pdo:=_class;
  3191. if (owner^.symtabletype<>localsymtable) then
  3192. while assigned(pdo) do
  3193. begin
  3194. if pdo^.symtable<>aktrecordsymtable then
  3195. dec(local_symtable_index);
  3196. pdo:=pdo^.childof;
  3197. end;
  3198. {$endif ndef NOLOCALBROWSER}
  3199. end;
  3200. end;
  3201. destructor tprocdef.done;
  3202. begin
  3203. if assigned(defref) then
  3204. begin
  3205. defref^.freechain;
  3206. dispose(defref,done);
  3207. end;
  3208. aliasnames.free;
  3209. if assigned(parast) then
  3210. dispose(parast,done);
  3211. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  3212. dispose(localst,done);
  3213. if (pocall_inline in proccalloptions) and assigned(code) then
  3214. tnode(code).free;
  3215. if assigned(regvarinfo) then
  3216. dispose(pregvarinfo(regvarinfo));
  3217. if (po_msgstr in procoptions) then
  3218. strdispose(messageinf.str);
  3219. if assigned(_mangledname) then
  3220. stringdispose(_mangledname);
  3221. inherited done;
  3222. end;
  3223. procedure tprocdef.write;
  3224. var
  3225. oldintfcrc : boolean;
  3226. begin
  3227. inherited write;
  3228. oldintfcrc:=current_ppu^.do_interface_crc;
  3229. current_ppu^.do_interface_crc:=false;
  3230. { set all registers to used for simplified compilation PM }
  3231. if simplify_ppu then
  3232. begin
  3233. {$ifdef newcg}
  3234. usedregisters:=[firstreg..lastreg];
  3235. {$else newcg}
  3236. {$ifdef i386}
  3237. usedregisters:=$ff;
  3238. {$endif i386}
  3239. {$ifdef m68k}
  3240. usedregisters:=$ffff;
  3241. {$endif}
  3242. {$endif newcg}
  3243. end;
  3244. {$ifdef newcg}
  3245. writenormalset(usedregisters);
  3246. {$else newcg}
  3247. {$ifdef i386}
  3248. writebyte(usedregisters);
  3249. {$endif i386}
  3250. {$ifdef m68k}
  3251. writeword(usedregisters);
  3252. {$endif}
  3253. {$endif newcg}
  3254. current_ppu^.do_interface_crc:=oldintfcrc;
  3255. writestring(mangledname);
  3256. writelong(extnumber);
  3257. if (proctypeoption<>potype_operator) then
  3258. writederef(nextoverloaded)
  3259. else
  3260. begin
  3261. { only write the overloads from the same unit }
  3262. if assigned(nextoverloaded) and
  3263. (nextoverloaded^.owner=owner) then
  3264. writederef(nextoverloaded)
  3265. else
  3266. writederef(nil);
  3267. end;
  3268. writederef(_class);
  3269. writeposinfo(fileinfo);
  3270. if (pocall_inline in proccalloptions) then
  3271. begin
  3272. { we need to save
  3273. - the para and the local symtable
  3274. - the code ptree !! PM
  3275. writesymtable(parast);
  3276. writesymtable(localst);
  3277. writeptree(ptree(code));
  3278. }
  3279. end;
  3280. current_ppu^.writeentry(ibprocdef);
  3281. { Save the para and local symtable, for easier reading
  3282. save both always, they don't influence the interface crc }
  3283. oldintfcrc:=current_ppu^.do_interface_crc;
  3284. current_ppu^.do_interface_crc:=false;
  3285. if not assigned(parast) then
  3286. begin
  3287. parast:=new(pstoredsymtable,init(parasymtable));
  3288. parast^.defowner:=@self;
  3289. end;
  3290. pstoredsymtable(parast)^.writeas;
  3291. {if not assigned(localst) then
  3292. begin
  3293. localst:=new(pstoredsymtable,init(localsymtable));
  3294. localst^.defowner:=@self;
  3295. end;
  3296. localst^.writeas;}
  3297. current_ppu^.do_interface_crc:=oldintfcrc;
  3298. end;
  3299. function tprocdef.haspara:boolean;
  3300. begin
  3301. haspara:=assigned(parast^.symindex^.first);
  3302. end;
  3303. {$ifdef GDB}
  3304. procedure addparaname(p : psym);
  3305. var vs : char;
  3306. begin
  3307. if pvarsym(p)^.varspez = vs_value then vs := '1'
  3308. else vs := '0';
  3309. strpcopy(strend(StabRecString),p^.name+':'+pstoreddef(pvarsym(p)^.vartype.def)^.numberstring+','+vs+';');
  3310. end;
  3311. function tprocdef.stabstring : pchar;
  3312. var
  3313. i : longint;
  3314. oldrec : pchar;
  3315. begin
  3316. oldrec := stabrecstring;
  3317. getmem(StabRecString,1024);
  3318. strpcopy(StabRecString,'f'+pstoreddef(rettype.def)^.numberstring);
  3319. i:=maxparacount;
  3320. if i>0 then
  3321. begin
  3322. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3323. (* confuse gdb !! PM
  3324. if assigned(parast) then
  3325. parast^.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3326. else
  3327. begin
  3328. param := para1;
  3329. i := 0;
  3330. while assigned(param) do
  3331. begin
  3332. inc(i);
  3333. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3334. {Here we have lost the parameter names !!}
  3335. {using lower case parameters }
  3336. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3337. +':'+param^.paratype.def^.numberstring+','+vartyp+';');
  3338. param := param^.next;
  3339. end;
  3340. end; *)
  3341. {strpcopy(strend(StabRecString),';');}
  3342. end;
  3343. stabstring := strnew(stabrecstring);
  3344. freemem(stabrecstring,1024);
  3345. stabrecstring := oldrec;
  3346. end;
  3347. procedure tprocdef.concatstabto(asmlist : taasmoutput);
  3348. begin
  3349. end;
  3350. {$endif GDB}
  3351. procedure tprocdef.deref;
  3352. var
  3353. oldsymtablestack,
  3354. oldlocalsymtable : psymtable;
  3355. begin
  3356. inherited deref;
  3357. resolvedef(pdef(nextoverloaded));
  3358. resolvedef(pdef(_class));
  3359. { parast }
  3360. oldsymtablestack:=symtablestack;
  3361. oldlocalsymtable:=aktlocalsymtable;
  3362. aktlocalsymtable:=parast;
  3363. pstoredsymtable(parast)^.deref;
  3364. {symtablestack:=parast;
  3365. aktlocalsymtable:=localst;
  3366. localst^.deref;}
  3367. aktlocalsymtable:=oldlocalsymtable;
  3368. symtablestack:=oldsymtablestack;
  3369. end;
  3370. function tprocdef.mangledname : string;
  3371. begin
  3372. if assigned(_mangledname) then
  3373. mangledname:=_mangledname^
  3374. else
  3375. mangledname:='';
  3376. if count then
  3377. is_used:=true;
  3378. end;
  3379. function tprocdef.cplusplusmangledname : string;
  3380. function getcppparaname(p : pdef) : string;
  3381. const
  3382. ordtype2str : array[tbasetype] of string[2] = (
  3383. '','','c',
  3384. 'Uc','Us','Ui',
  3385. 'Sc','s','i',
  3386. 'b','b','b',
  3387. 'Us','x','w');
  3388. var
  3389. s : string;
  3390. begin
  3391. case p^.deftype of
  3392. orddef:
  3393. s:=ordtype2str[porddef(p)^.typ];
  3394. pointerdef:
  3395. s:='P'+getcppparaname(ppointerdef(p)^.pointertype.def);
  3396. else
  3397. internalerror(2103001);
  3398. end;
  3399. getcppparaname:=s;
  3400. end;
  3401. var
  3402. s,s2 : string;
  3403. param : TParaItem;
  3404. begin
  3405. s := procsym^.realname;
  3406. if procsym^.owner^.symtabletype=objectsymtable then
  3407. begin
  3408. s2:=upper(pobjectdef(procsym^.owner^.defowner)^.typesym^.realname);
  3409. case proctypeoption of
  3410. potype_destructor:
  3411. s:='_$_'+tostr(length(s2))+s2;
  3412. potype_constructor:
  3413. s:='___'+tostr(length(s2))+s2;
  3414. else
  3415. s:='_'+s+'__'+tostr(length(s2))+s2;
  3416. end;
  3417. end
  3418. else s:=s+'__';
  3419. s:=s+'F';
  3420. { concat modifiers }
  3421. { !!!!! }
  3422. { now we handle the parameters }
  3423. param := TParaItem(Para.first);
  3424. if assigned(param) then
  3425. while assigned(param) do
  3426. begin
  3427. s2:=getcppparaname(param.paratype.def);
  3428. if param.paratyp in [vs_var,vs_out] then
  3429. s2:='R'+s2;
  3430. s:=s+s2;
  3431. param:=TParaItem(param.next);
  3432. end
  3433. else
  3434. s:=s+'v';
  3435. cplusplusmangledname:=s;
  3436. end;
  3437. procedure tprocdef.setmangledname(const s : string);
  3438. begin
  3439. if assigned(_mangledname) then
  3440. begin
  3441. {$ifdef MEMDEBUG}
  3442. dec(manglenamesize,length(_mangledname^));
  3443. {$endif}
  3444. stringdispose(_mangledname);
  3445. end;
  3446. _mangledname:=stringdup(s);
  3447. {$ifdef MEMDEBUG}
  3448. inc(manglenamesize,length(s));
  3449. {$endif}
  3450. {$ifdef EXTDEBUG}
  3451. if assigned(parast) then
  3452. begin
  3453. stringdispose(parast^.name);
  3454. parast^.name:=stringdup('args of '+s);
  3455. end;
  3456. if assigned(localst) then
  3457. begin
  3458. stringdispose(localst^.name);
  3459. localst^.name:=stringdup('locals of '+s);
  3460. end;
  3461. {$endif}
  3462. end;
  3463. {***************************************************************************
  3464. TPROCVARDEF
  3465. ***************************************************************************}
  3466. constructor tprocvardef.init;
  3467. begin
  3468. inherited init;
  3469. deftype:=procvardef;
  3470. end;
  3471. constructor tprocvardef.load;
  3472. begin
  3473. inherited load;
  3474. deftype:=procvardef;
  3475. end;
  3476. procedure tprocvardef.write;
  3477. begin
  3478. { here we cannot get a real good value so just give something }
  3479. { plausible (PM) }
  3480. { a more secure way would be
  3481. to allways store in a temp }
  3482. if is_fpu(rettype.def) then
  3483. fpu_used:=2
  3484. else
  3485. fpu_used:=0;
  3486. inherited write;
  3487. current_ppu^.writeentry(ibprocvardef);
  3488. end;
  3489. function tprocvardef.size : longint;
  3490. begin
  3491. if (po_methodpointer in procoptions) then
  3492. size:=2*target_os.size_of_pointer
  3493. else
  3494. size:=target_os.size_of_pointer;
  3495. end;
  3496. {$ifdef GDB}
  3497. function tprocvardef.stabstring : pchar;
  3498. var
  3499. nss : pchar;
  3500. { i : longint; }
  3501. begin
  3502. { i := maxparacount; }
  3503. getmem(nss,1024);
  3504. { it is not a function but a function pointer !! (PM) }
  3505. strpcopy(nss,'*f'+pstoreddef(rettype.def)^.numberstring{+','+tostr(i)}+';');
  3506. { this confuses gdb !!
  3507. we should use 'F' instead of 'f' but
  3508. as we use c++ language mode
  3509. it does not like that either
  3510. Please do not remove this part
  3511. might be used once
  3512. gdb for pascal is ready PM }
  3513. (*
  3514. param := para1;
  3515. i := 0;
  3516. while assigned(param) do
  3517. begin
  3518. inc(i);
  3519. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3520. {Here we have lost the parameter names !!}
  3521. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
  3522. strcat(nss,pst);
  3523. strdispose(pst);
  3524. param := param^.next;
  3525. end; *)
  3526. {strpcopy(strend(nss),';');}
  3527. stabstring := strnew(nss);
  3528. freemem(nss,1024);
  3529. end;
  3530. procedure tprocvardef.concatstabto(asmlist : taasmoutput);
  3531. begin
  3532. if ( not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3533. and (is_def_stab_written = not_written) then
  3534. inherited concatstabto(asmlist);
  3535. is_def_stab_written:=written;
  3536. end;
  3537. {$endif GDB}
  3538. procedure tprocvardef.write_rtti_data;
  3539. var
  3540. pdc : TParaItem;
  3541. methodkind, paraspec : byte;
  3542. begin
  3543. if po_methodpointer in procoptions then
  3544. begin
  3545. { write method id and name }
  3546. rttiList.concat(Tai_const.Create_8bit(tkmethod));
  3547. write_rtti_name;
  3548. { write kind of method (can only be function or procedure)}
  3549. if rettype.def = pdef(voiddef) then { ### typecast shoudln't be necessary! (sg) }
  3550. methodkind := mkProcedure
  3551. else
  3552. methodkind := mkFunction;
  3553. rttiList.concat(Tai_const.Create_8bit(methodkind));
  3554. { get # of parameters }
  3555. rttiList.concat(Tai_const.Create_8bit(maxparacount));
  3556. { write parameter info. The parameters must be written in reverse order
  3557. if this method uses right to left parameter pushing! }
  3558. if (pocall_leftright in proccalloptions) then
  3559. pdc:=TParaItem(Para.last)
  3560. else
  3561. pdc:=TParaItem(Para.first);
  3562. while assigned(pdc) do
  3563. begin
  3564. case pdc.paratyp of
  3565. vs_value: paraspec := 0;
  3566. vs_const: paraspec := pfConst;
  3567. vs_var : paraspec := pfVar;
  3568. vs_out : paraspec := pfOut;
  3569. end;
  3570. { write flags for current parameter }
  3571. rttiList.concat(Tai_const.Create_8bit(paraspec));
  3572. { write name of current parameter ### how can I get this??? (sg)}
  3573. rttiList.concat(Tai_const.Create_8bit(0));
  3574. { write name of type of current parameter }
  3575. pstoreddef(pdc.paratype.def)^.write_rtti_name;
  3576. if (pocall_leftright in proccalloptions) then
  3577. pdc:=TParaItem(pdc.previous)
  3578. else
  3579. pdc:=TParaItem(pdc.next);
  3580. end;
  3581. { write name of result type }
  3582. pstoreddef(rettype.def)^.write_rtti_name;
  3583. end;
  3584. end;
  3585. procedure tprocvardef.write_child_rtti_data;
  3586. begin
  3587. {!!!!!!!!}
  3588. end;
  3589. function tprocvardef.is_publishable : boolean;
  3590. begin
  3591. is_publishable:=(po_methodpointer in procoptions);
  3592. end;
  3593. function tprocvardef.gettypename : string;
  3594. begin
  3595. if assigned(rettype.def) and
  3596. (rettype.def<>pdef(voiddef)) then
  3597. gettypename:='<procedure variable type of function'+demangled_paras+
  3598. ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
  3599. else
  3600. gettypename:='<procedure variable type of procedure'+demangled_paras+
  3601. ';'+proccalloption2str+'>';
  3602. end;
  3603. {***************************************************************************
  3604. TOBJECTDEF
  3605. ***************************************************************************}
  3606. {$ifdef GDB}
  3607. const
  3608. vtabletype : word = 0;
  3609. vtableassigned : boolean = false;
  3610. {$endif GDB}
  3611. constructor tobjectdef.init(ot : tobjectdeftype;const n : string;c : pobjectdef);
  3612. begin
  3613. inherited init;
  3614. objecttype:=ot;
  3615. deftype:=objectdef;
  3616. objectoptions:=[];
  3617. childof:=nil;
  3618. symtable:=new(pstoredsymtable,init(objectsymtable));
  3619. symtable^.name := stringdup(n);
  3620. { create space for vmt !! }
  3621. vmt_offset:=0;
  3622. symtable^.datasize:=0;
  3623. symtable^.defowner:=@self;
  3624. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  3625. lastvtableindex:=0;
  3626. set_parent(c);
  3627. objname:=stringdup(n);
  3628. { set up guid }
  3629. isiidguidvalid:=true; { default null guid }
  3630. fillchar(iidguid,sizeof(iidguid),0); { default null guid }
  3631. iidstr:=stringdup(''); { default is empty string }
  3632. { set£p implemented interfaces }
  3633. if objecttype in [odt_class,odt_interfacecorba] then
  3634. new(implementedinterfaces,init)
  3635. else
  3636. implementedinterfaces:=nil;
  3637. {$ifdef GDB}
  3638. writing_class_record_stab:=false;
  3639. {$endif GDB}
  3640. end;
  3641. constructor tobjectdef.load;
  3642. var
  3643. oldread_member : boolean;
  3644. i,implintfcount: longint;
  3645. begin
  3646. inherited load;
  3647. deftype:=objectdef;
  3648. objecttype:=tobjectdeftype(readbyte);
  3649. savesize:=readlong;
  3650. vmt_offset:=readlong;
  3651. objname:=stringdup(readstring);
  3652. childof:=pobjectdef(readderef);
  3653. readsmallset(objectoptions);
  3654. has_rtti:=boolean(readbyte);
  3655. { load guid }
  3656. iidstr:=nil;
  3657. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3658. begin
  3659. isiidguidvalid:=boolean(readbyte);
  3660. readguid(iidguid);
  3661. iidstr:=stringdup(readstring);
  3662. lastvtableindex:=readlong;
  3663. end;
  3664. { load implemented interfaces }
  3665. if objecttype in [odt_class,odt_interfacecorba] then
  3666. begin
  3667. new(implementedinterfaces,init);
  3668. implintfcount:=readlong;
  3669. for i:=1 to implintfcount do
  3670. begin
  3671. implementedinterfaces^.addintfref(pdef(readderef));
  3672. implementedinterfaces^.ioffsets(i)^:=readlong;
  3673. end;
  3674. end
  3675. else
  3676. implementedinterfaces:=nil;
  3677. oldread_member:=read_member;
  3678. read_member:=true;
  3679. symtable:=new(pstoredsymtable,loadas(objectsymtable));
  3680. read_member:=oldread_member;
  3681. symtable^.defowner:=@self;
  3682. symtable^.name := stringdup(objname^);
  3683. { handles the predefined class tobject }
  3684. { the last TOBJECT which is loaded gets }
  3685. { it ! }
  3686. if (childof=nil) and
  3687. (objecttype=odt_class) and
  3688. (upper(objname^)='TOBJECT') then
  3689. class_tobject:=@self;
  3690. if (childof=nil) and
  3691. (objecttype=odt_interfacecom) and
  3692. (upper(objname^)='IUNKNOWN') then
  3693. interface_iunknown:=@self;
  3694. {$ifdef GDB}
  3695. writing_class_record_stab:=false;
  3696. {$endif GDB}
  3697. end;
  3698. destructor tobjectdef.done;
  3699. begin
  3700. if assigned(symtable) then
  3701. dispose(symtable,done);
  3702. if (oo_is_forward in objectoptions) then
  3703. Message1(sym_e_class_forward_not_resolved,objname^);
  3704. stringdispose(objname);
  3705. stringdispose(iidstr);
  3706. if assigned(implementedinterfaces) then
  3707. dispose(implementedinterfaces,done);
  3708. inherited done;
  3709. end;
  3710. procedure tobjectdef.write;
  3711. var
  3712. oldread_member : boolean;
  3713. implintfcount : longint;
  3714. i : longint;
  3715. begin
  3716. inherited write;
  3717. writebyte(byte(objecttype));
  3718. writelong(size);
  3719. writelong(vmt_offset);
  3720. writestring(objname^);
  3721. writederef(childof);
  3722. writesmallset(objectoptions);
  3723. writebyte(byte(has_rtti));
  3724. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3725. begin
  3726. writebyte(byte(isiidguidvalid));
  3727. writeguid(iidguid);
  3728. writestring(iidstr^);
  3729. writelong(lastvtableindex);
  3730. end;
  3731. if objecttype in [odt_class,odt_interfacecorba] then
  3732. begin
  3733. implintfcount:=implementedinterfaces^.count;
  3734. writelong(implintfcount);
  3735. for i:=1 to implintfcount do
  3736. begin
  3737. writederef(implementedinterfaces^.interfaces(i));
  3738. writelong(implementedinterfaces^.ioffsets(i)^);
  3739. end;
  3740. end;
  3741. current_ppu^.writeentry(ibobjectdef);
  3742. oldread_member:=read_member;
  3743. read_member:=true;
  3744. pstoredsymtable(symtable)^.writeas;
  3745. read_member:=oldread_member;
  3746. end;
  3747. function tobjectdef.getsymtable(t:tgetsymtable):psymtable;
  3748. begin
  3749. if t=gs_record then
  3750. getsymtable:=symtable
  3751. else
  3752. getsymtable:=nil;
  3753. end;
  3754. procedure tobjectdef.deref;
  3755. var
  3756. oldrecsyms : psymtable;
  3757. begin
  3758. inherited deref;
  3759. resolvedef(pdef(childof));
  3760. oldrecsyms:=aktrecordsymtable;
  3761. aktrecordsymtable:=symtable;
  3762. pstoredsymtable(symtable)^.deref;
  3763. aktrecordsymtable:=oldrecsyms;
  3764. if objecttype in [odt_class,odt_interfacecorba] then
  3765. implementedinterfaces^.deref;
  3766. end;
  3767. procedure tobjectdef.set_parent( c : pobjectdef);
  3768. begin
  3769. { nothing to do if the parent was not forward !}
  3770. if assigned(childof) then
  3771. exit;
  3772. childof:=c;
  3773. { some options are inherited !! }
  3774. if assigned(c) then
  3775. begin
  3776. { only important for classes }
  3777. lastvtableindex:=c^.lastvtableindex;
  3778. objectoptions:=objectoptions+(c^.objectoptions*
  3779. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  3780. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3781. begin
  3782. { add the data of the anchestor class }
  3783. inc(symtable^.datasize,c^.symtable^.datasize);
  3784. if (oo_has_vmt in objectoptions) and
  3785. (oo_has_vmt in c^.objectoptions) then
  3786. dec(symtable^.datasize,target_os.size_of_pointer);
  3787. { if parent has a vmt field then
  3788. the offset is the same for the child PM }
  3789. if (oo_has_vmt in c^.objectoptions) or is_class(@self) then
  3790. begin
  3791. vmt_offset:=c^.vmt_offset;
  3792. include(objectoptions,oo_has_vmt);
  3793. end;
  3794. end;
  3795. end;
  3796. savesize := symtable^.datasize;
  3797. end;
  3798. procedure tobjectdef.insertvmt;
  3799. begin
  3800. if objecttype in [odt_interfacecom,odt_interfacecorba] then exit;
  3801. if (oo_has_vmt in objectoptions) then
  3802. internalerror(12345)
  3803. else
  3804. begin
  3805. { first round up to multiple of 4 }
  3806. if (symtable^.dataalignment=2) then
  3807. begin
  3808. if (symtable^.datasize and 1)<>0 then
  3809. inc(symtable^.datasize);
  3810. end
  3811. else
  3812. if (symtable^.dataalignment>=4) then
  3813. begin
  3814. if (symtable^.datasize mod 4) <> 0 then
  3815. inc(symtable^.datasize,4-(symtable^.datasize mod 4));
  3816. end;
  3817. vmt_offset:=symtable^.datasize;
  3818. inc(symtable^.datasize,target_os.size_of_pointer);
  3819. include(objectoptions,oo_has_vmt);
  3820. end;
  3821. end;
  3822. procedure tobjectdef.check_forwards;
  3823. begin
  3824. if objecttype in [odt_interfacecom,odt_interfacecorba] then exit; { Kaz: ??? }
  3825. pstoredsymtable(symtable)^.check_forwards;
  3826. if (oo_is_forward in objectoptions) then
  3827. begin
  3828. { ok, in future, the forward can be resolved }
  3829. Message1(sym_e_class_forward_not_resolved,objname^);
  3830. exclude(objectoptions,oo_is_forward);
  3831. end;
  3832. end;
  3833. { true, if self inherits from d (or if they are equal) }
  3834. function tobjectdef.is_related(d : pobjectdef) : boolean;
  3835. var
  3836. hp : pobjectdef;
  3837. begin
  3838. hp:=@self;
  3839. while assigned(hp) do
  3840. begin
  3841. if hp=d then
  3842. begin
  3843. is_related:=true;
  3844. exit;
  3845. end;
  3846. hp:=hp^.childof;
  3847. end;
  3848. is_related:=false;
  3849. end;
  3850. var
  3851. sd : pprocdef;
  3852. procedure _searchdestructor(sym : pnamedindexobject);
  3853. var
  3854. p : pprocdef;
  3855. begin
  3856. { if we found already a destructor, then we exit }
  3857. if assigned(sd) then
  3858. exit;
  3859. if psym(sym)^.typ=procsym then
  3860. begin
  3861. p:=pprocsym(sym)^.definition;
  3862. while assigned(p) do
  3863. begin
  3864. if p^.proctypeoption=potype_destructor then
  3865. begin
  3866. sd:=p;
  3867. exit;
  3868. end;
  3869. p:=p^.nextoverloaded;
  3870. end;
  3871. end;
  3872. end;
  3873. function tobjectdef.searchdestructor : pprocdef;
  3874. var
  3875. o : pobjectdef;
  3876. begin
  3877. searchdestructor:=nil;
  3878. o:=@self;
  3879. sd:=nil;
  3880. while assigned(o) do
  3881. begin
  3882. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
  3883. if assigned(sd) then
  3884. begin
  3885. searchdestructor:=sd;
  3886. exit;
  3887. end;
  3888. o:=o^.childof;
  3889. end;
  3890. end;
  3891. function tobjectdef.size : longint;
  3892. begin
  3893. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3894. size:=target_os.size_of_pointer
  3895. else
  3896. size:=symtable^.datasize;
  3897. end;
  3898. function tobjectdef.alignment:longint;
  3899. begin
  3900. alignment:=symtable^.dataalignment;
  3901. end;
  3902. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3903. begin
  3904. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3905. case objecttype of
  3906. odt_class:
  3907. vmtmethodoffset:=(index+12)*target_os.size_of_pointer;
  3908. odt_interfacecom,odt_interfacecorba:
  3909. vmtmethodoffset:=index*target_os.size_of_pointer;
  3910. else
  3911. {$ifdef WITHDMT}
  3912. vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
  3913. {$else WITHDMT}
  3914. vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
  3915. {$endif WITHDMT}
  3916. end;
  3917. end;
  3918. function tobjectdef.vmt_mangledname : string;
  3919. {DM: I get a nil pointer on the owner name. I don't know if this
  3920. may happen, and I have therefore fixed the problem by doing nil pointer
  3921. checks.}
  3922. var
  3923. s1,s2:string;
  3924. begin
  3925. if not(oo_has_vmt in objectoptions) then
  3926. Message1(parser_object_has_no_vmt,objname^);
  3927. if owner^.name=nil then
  3928. s1:=''
  3929. else
  3930. s1:=upper(owner^.name^);
  3931. if objname=nil then
  3932. s2:=''
  3933. else
  3934. s2:=Upper(objname^);
  3935. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3936. end;
  3937. function tobjectdef.rtti_name : string;
  3938. var
  3939. s1,s2:string;
  3940. begin
  3941. if owner^.name=nil then
  3942. s1:=''
  3943. else
  3944. s1:=upper(owner^.name^);
  3945. if objname=nil then
  3946. s2:=''
  3947. else
  3948. s2:=Upper(objname^);
  3949. rtti_name:='RTTI_'+s1+'$_'+s2;
  3950. end;
  3951. {$ifdef GDB}
  3952. procedure addprocname(p :pnamedindexobject);
  3953. var virtualind,argnames : string;
  3954. news, newrec : pchar;
  3955. pd,ipd : pprocdef;
  3956. lindex : longint;
  3957. para : TParaItem;
  3958. arglength : byte;
  3959. sp : char;
  3960. begin
  3961. If psym(p)^.typ = procsym then
  3962. begin
  3963. pd := pprocsym(p)^.definition;
  3964. { this will be used for full implementation of object stabs
  3965. not yet done }
  3966. ipd := pd;
  3967. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  3968. if (po_virtualmethod in pd^.procoptions) then
  3969. begin
  3970. lindex := pd^.extnumber;
  3971. {doesnt seem to be necessary
  3972. lindex := lindex or $80000000;}
  3973. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.classnumberstring+';'
  3974. end
  3975. else
  3976. virtualind := '.';
  3977. { used by gdbpas to recognize constructor and destructors }
  3978. if (pd^.proctypeoption=potype_constructor) then
  3979. argnames:='__ct__'
  3980. else if (pd^.proctypeoption=potype_destructor) then
  3981. argnames:='__dt__'
  3982. else
  3983. argnames := '';
  3984. { arguments are not listed here }
  3985. {we don't need another definition}
  3986. para := TParaItem(pd^.Para.first);
  3987. while assigned(para) do
  3988. begin
  3989. if Para.paratype.def^.deftype = formaldef then
  3990. begin
  3991. if Para.paratyp=vs_var then
  3992. argnames := argnames+'3var'
  3993. else if Para.paratyp=vs_const then
  3994. argnames:=argnames+'5const'
  3995. else if Para.paratyp=vs_out then
  3996. argnames:=argnames+'3out';
  3997. end
  3998. else
  3999. begin
  4000. { if the arg definition is like (v: ^byte;..
  4001. there is no sym attached to data !!! }
  4002. if assigned(Para.paratype.def^.typesym) then
  4003. begin
  4004. arglength := length(Para.paratype.def^.typesym^.name);
  4005. argnames := argnames + tostr(arglength)+Para.paratype.def^.typesym^.name;
  4006. end
  4007. else
  4008. begin
  4009. argnames:=argnames+'11unnamedtype';
  4010. end;
  4011. end;
  4012. para := TParaItem(Para.next);
  4013. end;
  4014. ipd^.is_def_stab_written := written;
  4015. { here 2A must be changed for private and protected }
  4016. { 0 is private 1 protected and 2 public }
  4017. if (sp_private in psym(p)^.symoptions) then sp:='0'
  4018. else if (sp_protected in psym(p)^.symoptions) then sp:='1'
  4019. else sp:='2';
  4020. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  4021. +'=##'+pstoreddef(pd^.rettype.def)^.numberstring+';:'+argnames+';'+sp+'A'
  4022. +virtualind+';');
  4023. { get spare place for a string at the end }
  4024. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  4025. begin
  4026. getmem(news,stabrecsize+memsizeinc);
  4027. strcopy(news,stabrecstring);
  4028. freemem(stabrecstring,stabrecsize);
  4029. stabrecsize:=stabrecsize+memsizeinc;
  4030. stabrecstring:=news;
  4031. end;
  4032. strcat(StabRecstring,newrec);
  4033. {freemem(newrec,memsizeinc); }
  4034. strdispose(newrec);
  4035. {This should be used for case !!
  4036. RecOffset := RecOffset + pd^.size;}
  4037. end;
  4038. end;
  4039. function tobjectdef.stabstring : pchar;
  4040. var anc : pobjectdef;
  4041. oldrec : pchar;
  4042. oldrecsize,oldrecoffset : longint;
  4043. str_end : string;
  4044. begin
  4045. if not (objecttype=odt_class) or writing_class_record_stab then
  4046. begin
  4047. oldrec := stabrecstring;
  4048. oldrecsize:=stabrecsize;
  4049. stabrecsize:=memsizeinc;
  4050. GetMem(stabrecstring,stabrecsize);
  4051. strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
  4052. if assigned(childof) then
  4053. begin
  4054. {only one ancestor not virtual, public, at base offset 0 }
  4055. { !1 , 0 2 0 , }
  4056. strpcopy(strend(stabrecstring),'!1,020,'+childof^.classnumberstring+';');
  4057. end;
  4058. {virtual table to implement yet}
  4059. OldRecOffset:=RecOffset;
  4060. RecOffset := 0;
  4061. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  4062. RecOffset:=OldRecOffset;
  4063. if (oo_has_vmt in objectoptions) then
  4064. if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
  4065. begin
  4066. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  4067. +','+tostr(vmt_offset*8)+';');
  4068. end;
  4069. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
  4070. if (oo_has_vmt in objectoptions) then
  4071. begin
  4072. anc := @self;
  4073. while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
  4074. anc := anc^.childof;
  4075. { just in case anc = self }
  4076. str_end:=';~%'+anc^.classnumberstring+';';
  4077. end
  4078. else
  4079. str_end:=';';
  4080. strpcopy(strend(stabrecstring),str_end);
  4081. stabstring := strnew(StabRecString);
  4082. freemem(stabrecstring,stabrecsize);
  4083. stabrecstring := oldrec;
  4084. stabrecsize:=oldrecsize;
  4085. end
  4086. else
  4087. begin
  4088. stabstring:=strpnew('*'+classnumberstring);
  4089. end;
  4090. end;
  4091. procedure tobjectdef.set_globalnb;
  4092. begin
  4093. globalnb:=PglobalTypeCount^;
  4094. inc(PglobalTypeCount^);
  4095. { classes need two type numbers, the globalnb is set to the ptr }
  4096. if objecttype=odt_class then
  4097. begin
  4098. globalnb:=PGlobalTypeCount^;
  4099. inc(PglobalTypeCount^);
  4100. end;
  4101. end;
  4102. function tobjectdef.classnumberstring : string;
  4103. begin
  4104. { write stabs again if needed }
  4105. numberstring;
  4106. if objecttype=odt_class then
  4107. begin
  4108. dec(globalnb);
  4109. classnumberstring:=numberstring;
  4110. inc(globalnb);
  4111. end
  4112. else
  4113. classnumberstring:=numberstring;
  4114. end;
  4115. function tobjectdef.allstabstring : pchar;
  4116. var stabchar : string[2];
  4117. ss,st : pchar;
  4118. sname : string;
  4119. sym_line_no : longint;
  4120. begin
  4121. ss := stabstring;
  4122. getmem(st,strlen(ss)+512);
  4123. stabchar := 't';
  4124. if deftype in tagtypes then
  4125. stabchar := 'Tt';
  4126. if assigned(typesym) then
  4127. begin
  4128. sname := typesym^.name;
  4129. sym_line_no:=typesym^.fileinfo.line;
  4130. end
  4131. else
  4132. begin
  4133. sname := ' ';
  4134. sym_line_no:=0;
  4135. end;
  4136. if writing_class_record_stab then
  4137. strpcopy(st,'"'+sname+':'+stabchar+classnumberstring+'=')
  4138. else
  4139. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  4140. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  4141. allstabstring := strnew(st);
  4142. freemem(st,strlen(ss)+512);
  4143. strdispose(ss);
  4144. end;
  4145. procedure tobjectdef.concatstabto(asmlist : taasmoutput);
  4146. var st : pstring;
  4147. begin
  4148. if objecttype<>odt_class then
  4149. begin
  4150. inherited concatstabto(asmlist);
  4151. exit;
  4152. end;
  4153. if ((typesym=nil) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  4154. (is_def_stab_written = not_written) then
  4155. begin
  4156. if globalnb=0 then
  4157. set_globalnb;
  4158. { Write the record class itself }
  4159. writing_class_record_stab:=true;
  4160. inherited concatstabto(asmlist);
  4161. writing_class_record_stab:=false;
  4162. { Write the invisible pointer class }
  4163. is_def_stab_written:=not_written;
  4164. if assigned(typesym) then
  4165. begin
  4166. st:=typesym^._name;
  4167. typesym^._name:=stringdup(' ');
  4168. end;
  4169. inherited concatstabto(asmlist);
  4170. if assigned(typesym) then
  4171. begin
  4172. stringdispose(typesym^._name);
  4173. typesym^._name:=st;
  4174. end;
  4175. end;
  4176. end;
  4177. {$endif GDB}
  4178. procedure tobjectdef.write_child_init_data;
  4179. begin
  4180. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  4181. end;
  4182. procedure tobjectdef.write_init_data;
  4183. begin
  4184. case objecttype of
  4185. odt_class:
  4186. rttiList.concat(Tai_const.Create_8bit(tkclass));
  4187. odt_object:
  4188. rttiList.concat(Tai_const.Create_8bit(tkobject));
  4189. odt_interfacecom:
  4190. rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4191. odt_interfacecorba:
  4192. rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4193. else
  4194. exit;
  4195. end;
  4196. { generate the name }
  4197. rttiList.concat(Tai_const.Create_8bit(length(objname^)));
  4198. rttiList.concat(Tai_string.Create(objname^));
  4199. rttiList.concat(Tai_const.Create_32bit(size));
  4200. count:=0;
  4201. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4202. begin
  4203. end
  4204. else
  4205. begin
  4206. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  4207. rttiList.concat(Tai_const.Create_32bit(count));
  4208. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  4209. end;
  4210. end;
  4211. function tobjectdef.needs_inittable : boolean;
  4212. var
  4213. oldb : boolean;
  4214. begin
  4215. case objecttype of
  4216. odt_interfacecom: needs_inittable:=true;
  4217. odt_interfacecorba:
  4218. needs_inittable:=is_related(interface_iunknown);
  4219. odt_object:
  4220. begin
  4221. { there are recursive calls to needs_inittable possible, }
  4222. { so we have to change to old value how else should }
  4223. { we do that ? check_rec_rtti can't be a nested }
  4224. { procedure of needs_rtti ! }
  4225. oldb:=binittable;
  4226. binittable:=false;
  4227. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
  4228. needs_inittable:=binittable;
  4229. binittable:=oldb;
  4230. end;
  4231. else needs_inittable:=false;
  4232. end;
  4233. end;
  4234. procedure count_published_properties(sym:pnamedindexobject);
  4235. begin
  4236. if needs_prop_entry(psym(sym)) and
  4237. (psym(sym)^.typ<>varsym) then
  4238. inc(count);
  4239. end;
  4240. procedure write_property_info(sym : pnamedindexobject);
  4241. var
  4242. proctypesinfo : byte;
  4243. procedure writeproc(proc : psymlist; shiftvalue : byte);
  4244. var
  4245. typvalue : byte;
  4246. hp : psymlistitem;
  4247. address : longint;
  4248. begin
  4249. if not(assigned(proc) and assigned(proc^.firstsym)) then
  4250. begin
  4251. rttiList.concat(Tai_const.Create_32bit(1));
  4252. typvalue:=3;
  4253. end
  4254. else if proc^.firstsym^.sym^.typ=varsym then
  4255. begin
  4256. address:=0;
  4257. hp:=proc^.firstsym;
  4258. while assigned(hp) do
  4259. begin
  4260. inc(address,pvarsym(hp^.sym)^.address);
  4261. hp:=hp^.next;
  4262. end;
  4263. rttiList.concat(Tai_const.Create_32bit(address));
  4264. typvalue:=0;
  4265. end
  4266. else
  4267. begin
  4268. if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
  4269. begin
  4270. rttiList.concat(Tai_const_symbol.Createname(pprocdef(proc^.def)^.mangledname));
  4271. typvalue:=1;
  4272. end
  4273. else
  4274. begin
  4275. { virtual method, write vmt offset }
  4276. rttiList.concat(Tai_const.Create_32bit(
  4277. pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber)));
  4278. typvalue:=2;
  4279. end;
  4280. end;
  4281. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4282. end;
  4283. begin
  4284. if needs_prop_entry(psym(sym)) then
  4285. case psym(sym)^.typ of
  4286. varsym:
  4287. begin
  4288. {$ifdef dummy}
  4289. if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
  4290. not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
  4291. internalerror(1509992);
  4292. { access to implicit class property as field }
  4293. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4294. rttiList.concat(Tai_const_symbol.Createname(pvarsym(sym^.vartype.def^.get_rtti_label)));
  4295. rttiList.concat(Tai_const.Create_32bit(pvarsym(sym^.address)));
  4296. rttiList.concat(Tai_const.Create_32bit(pvarsym(sym^.address)));
  4297. { per default stored }
  4298. rttiList.concat(Tai_const.Create_32bit(1));
  4299. { index as well as ... }
  4300. rttiList.concat(Tai_const.Create_32bit(0));
  4301. { default value are zero }
  4302. rttiList.concat(Tai_const.Create_32bit(0));
  4303. rttiList.concat(Tai_const.Create_16bit(count));
  4304. inc(count);
  4305. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4306. rttiList.concat(Tai_const.Create_8bit(length(pvarsym(sym^.realname))));
  4307. rttiList.concat(Tai_string.Create(pvarsym(sym^.realname)));
  4308. {$endif dummy}
  4309. end;
  4310. propertysym:
  4311. begin
  4312. if ppo_indexed in ppropertysym(sym)^.propoptions then
  4313. proctypesinfo:=$40
  4314. else
  4315. proctypesinfo:=0;
  4316. rttiList.concat(Tai_const_symbol.Createname(ppropertysym(sym)^.proptype.def^.get_rtti_label));
  4317. writeproc(ppropertysym(sym)^.readaccess,0);
  4318. writeproc(ppropertysym(sym)^.writeaccess,2);
  4319. { isn't it stored ? }
  4320. if not(ppo_stored in ppropertysym(sym)^.propoptions) then
  4321. begin
  4322. rttiList.concat(Tai_const.Create_32bit(0));
  4323. proctypesinfo:=proctypesinfo or (3 shl 4);
  4324. end
  4325. else
  4326. writeproc(ppropertysym(sym)^.storedaccess,4);
  4327. rttiList.concat(Tai_const.Create_32bit(ppropertysym(sym)^.index));
  4328. rttiList.concat(Tai_const.Create_32bit(ppropertysym(sym)^.default));
  4329. rttiList.concat(Tai_const.Create_16bit(count));
  4330. inc(count);
  4331. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4332. rttiList.concat(Tai_const.Create_8bit(length(ppropertysym(sym)^.realname)));
  4333. rttiList.concat(Tai_string.Create(ppropertysym(sym)^.realname));
  4334. end;
  4335. else internalerror(1509992);
  4336. end;
  4337. end;
  4338. procedure generate_published_child_rtti(sym : pnamedindexobject);
  4339. begin
  4340. if needs_prop_entry(psym(sym)) then
  4341. case psym(sym)^.typ of
  4342. varsym:
  4343. ;
  4344. { now ignored:
  4345. pvarsym(sym)^.vartype.def^.get_rtti_label;
  4346. }
  4347. propertysym:
  4348. ppropertysym(sym)^.proptype.def^.get_rtti_label;
  4349. else
  4350. internalerror(1509991);
  4351. end;
  4352. end;
  4353. procedure tobjectdef.write_child_rtti_data;
  4354. begin
  4355. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
  4356. end;
  4357. procedure tobjectdef.generate_rtti;
  4358. begin
  4359. if not has_rtti then
  4360. begin
  4361. has_rtti:=true;
  4362. getdatalabel(rtti_label);
  4363. write_child_rtti_data;
  4364. rttiList.concat(Tai_symbol.Createname_global(rtti_name,0));
  4365. rttiList.concat(Tai_label.Create(rtti_label));
  4366. write_rtti_data;
  4367. rttiList.concat(Tai_symbol_end.Createname(rtti_name));
  4368. end;
  4369. end;
  4370. type
  4371. tclasslistitem = class(tlinkedlistitem)
  4372. index : longint;
  4373. p : pobjectdef;
  4374. end;
  4375. var
  4376. classtablelist : tlinkedlist;
  4377. tablecount : longint;
  4378. function searchclasstablelist(p : pobjectdef) : tclasslistitem;
  4379. var
  4380. hp : tclasslistitem;
  4381. begin
  4382. hp:=tclasslistitem(classtablelist.first);
  4383. while assigned(hp) do
  4384. if hp.p=p then
  4385. begin
  4386. searchclasstablelist:=hp;
  4387. exit;
  4388. end
  4389. else
  4390. hp:=tclasslistitem(hp.next);
  4391. searchclasstablelist:=nil;
  4392. end;
  4393. procedure count_published_fields(sym:pnamedindexobject);
  4394. var
  4395. hp : tclasslistitem;
  4396. begin
  4397. if needs_prop_entry(psym(sym)) and
  4398. (psym(sym)^.typ=varsym) then
  4399. begin
  4400. if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
  4401. internalerror(0206001);
  4402. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  4403. if not(assigned(hp)) then
  4404. begin
  4405. hp:=tclasslistitem.create;
  4406. hp.p:=pobjectdef(pvarsym(sym)^.vartype.def);
  4407. hp.index:=tablecount;
  4408. classtablelist.concat(hp);
  4409. inc(tablecount);
  4410. end;
  4411. inc(count);
  4412. end;
  4413. end;
  4414. procedure writefields(sym:pnamedindexobject);
  4415. var
  4416. hp : tclasslistitem;
  4417. begin
  4418. if needs_prop_entry(psym(sym)) and
  4419. (psym(sym)^.typ=varsym) then
  4420. begin
  4421. rttiList.concat(Tai_const.Create_32bit(pvarsym(sym)^.address));
  4422. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  4423. if not(assigned(hp)) then
  4424. internalerror(0206002);
  4425. rttiList.concat(Tai_const.Create_16bit(hp.index));
  4426. rttiList.concat(Tai_const.Create_8bit(length(pvarsym(sym)^.realname)));
  4427. rttiList.concat(Tai_string.Create(pvarsym(sym)^.realname));
  4428. end;
  4429. end;
  4430. function tobjectdef.generate_field_table : pasmlabel;
  4431. var
  4432. fieldtable,
  4433. classtable : pasmlabel;
  4434. hp : tclasslistitem;
  4435. begin
  4436. classtablelist:=TLinkedList.Create;
  4437. getdatalabel(fieldtable);
  4438. getdatalabel(classtable);
  4439. count:=0;
  4440. tablecount:=0;
  4441. symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
  4442. rttiList.concat(Tai_label.Create(fieldtable));
  4443. rttiList.concat(Tai_const.Create_16bit(count));
  4444. rttiList.concat(Tai_const_symbol.Create(classtable));
  4445. symtable^.foreach({$ifdef FPC}@{$endif}writefields);
  4446. { generate the class table }
  4447. rttiList.concat(Tai_label.Create(classtable));
  4448. rttiList.concat(Tai_const.Create_16bit(tablecount));
  4449. hp:=tclasslistitem(classtablelist.first);
  4450. while assigned(hp) do
  4451. begin
  4452. rttiList.concat(Tai_const_symbol.Createname(pobjectdef(hp.p)^.vmt_mangledname));
  4453. hp:=tclasslistitem(hp.next);
  4454. end;
  4455. generate_field_table:=fieldtable;
  4456. classtablelist.free;
  4457. end;
  4458. function tobjectdef.next_free_name_index : longint;
  4459. var
  4460. i : longint;
  4461. begin
  4462. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4463. i:=childof^.next_free_name_index
  4464. else
  4465. i:=0;
  4466. count:=0;
  4467. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4468. next_free_name_index:=i+count;
  4469. end;
  4470. procedure tobjectdef.write_rtti_data;
  4471. begin
  4472. case objecttype of
  4473. odt_class: rttiList.concat(Tai_const.Create_8bit(tkclass));
  4474. odt_object: rttiList.concat(Tai_const.Create_8bit(tkobject));
  4475. odt_interfacecom: rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4476. odt_interfacecorba: rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4477. else
  4478. exit;
  4479. end;
  4480. { generate the name }
  4481. rttiList.concat(Tai_const.Create_8bit(length(objname^)));
  4482. rttiList.concat(Tai_string.Create(objname^));
  4483. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4484. rttiList.concat(Tai_const.Create_32bit(0))
  4485. else
  4486. rttiList.concat(Tai_const_symbol.Createname(vmt_mangledname));
  4487. { write owner typeinfo }
  4488. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4489. rttiList.concat(Tai_const_symbol.Createname(childof^.get_rtti_label))
  4490. else
  4491. rttiList.concat(Tai_const.Create_32bit(0));
  4492. { count total number of properties }
  4493. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4494. count:=childof^.next_free_name_index
  4495. else
  4496. count:=0;
  4497. { write it }
  4498. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4499. rttiList.concat(Tai_const.Create_16bit(count));
  4500. { write unit name }
  4501. rttiList.concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4502. rttiList.concat(Tai_string.Create(current_module.realmodulename^));
  4503. { write published properties count }
  4504. count:=0;
  4505. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4506. rttiList.concat(Tai_const.Create_16bit(count));
  4507. { count is used to write nameindex }
  4508. { but we need an offset of the owner }
  4509. { to give each property an own slot }
  4510. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4511. count:=childof^.next_free_name_index
  4512. else
  4513. count:=0;
  4514. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
  4515. end;
  4516. function tobjectdef.is_publishable : boolean;
  4517. begin
  4518. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4519. end;
  4520. function tobjectdef.get_rtti_label : string;
  4521. begin
  4522. generate_rtti;
  4523. get_rtti_label:=rtti_name;
  4524. end;
  4525. {****************************************************************************
  4526. TIMPLEMENTEDINTERFACES
  4527. ****************************************************************************}
  4528. type
  4529. pnamemap = ^tnamemap;
  4530. tnamemap = object(tnamedindexobject)
  4531. newname: pstring;
  4532. constructor init(const aname, anewname: string);
  4533. destructor done; virtual;
  4534. end;
  4535. constructor tnamemap.init(const aname, anewname: string);
  4536. begin
  4537. inherited initname(name);
  4538. newname:=stringdup(anewname);
  4539. end;
  4540. destructor tnamemap.done;
  4541. begin
  4542. stringdispose(newname);
  4543. inherited done;
  4544. end;
  4545. type
  4546. pprocdefstore = ^tprocdefstore;
  4547. tprocdefstore = object(tnamedindexobject)
  4548. procdef: pprocdef;
  4549. constructor init(aprocdef: pprocdef);
  4550. end;
  4551. constructor tprocdefstore.init(aprocdef: pprocdef);
  4552. begin
  4553. inherited init;
  4554. procdef:=aprocdef;
  4555. end;
  4556. type
  4557. pimplintfentry = ^timplintfentry;
  4558. timplintfentry = object(tnamedindexobject)
  4559. intf: pobjectdef;
  4560. ioffs: longint;
  4561. namemappings: pdictionary;
  4562. procdefs: pindexarray;
  4563. constructor init(aintf: pobjectdef);
  4564. destructor done; virtual;
  4565. end;
  4566. constructor timplintfentry.init(aintf: pobjectdef);
  4567. begin
  4568. inherited init;
  4569. intf:=aintf;
  4570. ioffs:=-1;
  4571. namemappings:=nil;
  4572. procdefs:=nil;
  4573. end;
  4574. destructor timplintfentry.done;
  4575. begin
  4576. if assigned(namemappings) then
  4577. dispose(namemappings,done);
  4578. if assigned(procdefs) then
  4579. dispose(procdefs,done);
  4580. inherited done;
  4581. end;
  4582. constructor timplementedinterfaces.init;
  4583. begin
  4584. finterfaces.init(1);
  4585. end;
  4586. destructor timplementedinterfaces.done;
  4587. begin
  4588. finterfaces.done;
  4589. end;
  4590. function timplementedinterfaces.count: longint;
  4591. begin
  4592. count:=finterfaces.count;
  4593. end;
  4594. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4595. begin
  4596. if (intfindex<1) or (intfindex>count) then
  4597. InternalError(200006123);
  4598. end;
  4599. function timplementedinterfaces.interfaces(intfindex: longint): pobjectdef;
  4600. begin
  4601. checkindex(intfindex);
  4602. interfaces:=pimplintfentry(finterfaces.search(intfindex))^.intf;
  4603. end;
  4604. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4605. begin
  4606. checkindex(intfindex);
  4607. ioffsets:=@pimplintfentry(finterfaces.search(intfindex))^.ioffs;
  4608. end;
  4609. function timplementedinterfaces.searchintf(def: pdef): longint;
  4610. var
  4611. i: longint;
  4612. begin
  4613. i:=1;
  4614. while (i<=count) and (pdef(interfaces(i))<>def) do inc(i);
  4615. if i<=count then
  4616. searchintf:=i
  4617. else
  4618. searchintf:=-1;
  4619. end;
  4620. procedure timplementedinterfaces.deref;
  4621. var
  4622. i: longint;
  4623. begin
  4624. for i:=1 to count do
  4625. with pimplintfentry(finterfaces.search(i))^ do
  4626. resolvedef(pdef(intf));
  4627. end;
  4628. procedure timplementedinterfaces.addintfref(def: pdef);
  4629. begin
  4630. finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
  4631. end;
  4632. procedure timplementedinterfaces.addintf(def: pdef);
  4633. begin
  4634. if not assigned(def) or (searchintf(def)<>-1) or (def^.deftype<>objectdef) or
  4635. not (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4636. internalerror(200006124);
  4637. finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
  4638. end;
  4639. procedure timplementedinterfaces.clearmappings;
  4640. var
  4641. i: longint;
  4642. begin
  4643. for i:=1 to count do
  4644. with pimplintfentry(finterfaces.search(i))^ do
  4645. begin
  4646. if assigned(namemappings) then
  4647. dispose(namemappings,done);
  4648. namemappings:=nil;
  4649. end;
  4650. end;
  4651. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4652. begin
  4653. checkindex(intfindex);
  4654. with pimplintfentry(finterfaces.search(intfindex))^ do
  4655. begin
  4656. if not assigned(namemappings) then
  4657. new(namemappings,init);
  4658. namemappings^.insert(new(pnamemap,init(name,newname)));
  4659. end;
  4660. end;
  4661. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4662. begin
  4663. checkindex(intfindex);
  4664. if not assigned(nextexist) then
  4665. with pimplintfentry(finterfaces.search(intfindex))^ do
  4666. begin
  4667. if assigned(namemappings) then
  4668. nextexist:=namemappings^.search(name)
  4669. else
  4670. nextexist:=nil;
  4671. end;
  4672. if assigned(nextexist) then
  4673. begin
  4674. getmappings:=pnamemap(nextexist)^.newname^;
  4675. nextexist:=pnamemap(nextexist)^.listnext;
  4676. end
  4677. else
  4678. getmappings:='';
  4679. end;
  4680. procedure timplementedinterfaces.clearimplprocs;
  4681. var
  4682. i: longint;
  4683. begin
  4684. for i:=1 to count do
  4685. with pimplintfentry(finterfaces.search(i))^ do
  4686. begin
  4687. if assigned(procdefs) then
  4688. dispose(procdefs,done);
  4689. procdefs:=nil;
  4690. end;
  4691. end;
  4692. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: pprocdef);
  4693. begin
  4694. checkindex(intfindex);
  4695. with pimplintfentry(finterfaces.search(intfindex))^ do
  4696. begin
  4697. if not assigned(procdefs) then
  4698. new(procdefs,init(4));
  4699. procdefs^.insert(new(pprocdefstore,init(procdef)));
  4700. end;
  4701. end;
  4702. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4703. begin
  4704. checkindex(intfindex);
  4705. with pimplintfentry(finterfaces.search(intfindex))^ do
  4706. if assigned(procdefs) then
  4707. implproccount:=procdefs^.count
  4708. else
  4709. implproccount:=0;
  4710. end;
  4711. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): pprocdef;
  4712. begin
  4713. checkindex(intfindex);
  4714. with pimplintfentry(finterfaces.search(intfindex))^ do
  4715. if assigned(procdefs) then
  4716. implprocs:=pprocdefstore(procdefs^.search(procindex))^.procdef
  4717. else
  4718. internalerror(200006131);
  4719. end;
  4720. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4721. var
  4722. possible: boolean;
  4723. i: longint;
  4724. iiep1: pindexarray;
  4725. iiep2: pindexarray;
  4726. begin
  4727. checkindex(intfindex);
  4728. checkindex(remainindex);
  4729. iiep1:=pimplintfentry(finterfaces.search(intfindex))^.procdefs;
  4730. iiep2:=pimplintfentry(finterfaces.search(remainindex))^.procdefs;
  4731. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4732. begin
  4733. possible:=true;
  4734. weight:=0;
  4735. end
  4736. else
  4737. begin
  4738. possible:=assigned(iiep2) and (iiep1^.count<=iiep2^.count);
  4739. i:=1;
  4740. while (possible) and (i<=iiep1^.count) do
  4741. begin
  4742. possible:=
  4743. pprocdefstore(iiep1^.search(i))^.procdef=
  4744. pprocdefstore(iiep2^.search(i))^.procdef;
  4745. inc(i);
  4746. end;
  4747. if possible then
  4748. weight:=iiep1^.count;
  4749. end;
  4750. isimplmergepossible:=possible;
  4751. end;
  4752. {****************************************************************************
  4753. TFORWARDDEF
  4754. ****************************************************************************}
  4755. constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
  4756. var
  4757. oldregisterdef : boolean;
  4758. begin
  4759. { never register the forwarddefs, they are disposed at the
  4760. end of the type declaration block }
  4761. oldregisterdef:=registerdef;
  4762. registerdef:=false;
  4763. inherited init;
  4764. registerdef:=oldregisterdef;
  4765. deftype:=forwarddef;
  4766. tosymname:=s;
  4767. forwardpos:=pos;
  4768. end;
  4769. function tforwarddef.gettypename:string;
  4770. begin
  4771. gettypename:='unresolved forward to '+tosymname;
  4772. end;
  4773. {****************************************************************************
  4774. TERRORDEF
  4775. ****************************************************************************}
  4776. constructor terrordef.init;
  4777. begin
  4778. inherited init;
  4779. deftype:=errordef;
  4780. end;
  4781. {$ifdef GDB}
  4782. function terrordef.stabstring : pchar;
  4783. begin
  4784. stabstring:=strpnew('error'+numberstring);
  4785. end;
  4786. {$endif GDB}
  4787. function terrordef.gettypename:string;
  4788. begin
  4789. gettypename:='<erroneous type>';
  4790. end;
  4791. {****************************************************************************
  4792. GDB Helpers
  4793. ****************************************************************************}
  4794. {$ifdef GDB}
  4795. function typeglobalnumber(const s : string) : string;
  4796. var st : string;
  4797. symt : psymtable;
  4798. srsym : psym;
  4799. srsymtable : psymtable;
  4800. old_make_ref : boolean;
  4801. begin
  4802. old_make_ref:=make_ref;
  4803. make_ref:=false;
  4804. typeglobalnumber := '0';
  4805. srsym := nil;
  4806. if pos('.',s) > 0 then
  4807. begin
  4808. st := copy(s,1,pos('.',s)-1);
  4809. searchsym(st,srsym,srsymtable);
  4810. st := copy(s,pos('.',s)+1,255);
  4811. if assigned(srsym) then
  4812. begin
  4813. if srsym^.typ = unitsym then
  4814. begin
  4815. symt := punitsym(srsym)^.unitsymtable;
  4816. srsym := psym(symt^.search(st));
  4817. end else srsym := nil;
  4818. end;
  4819. end else st := s;
  4820. if srsym = nil then
  4821. searchsym(st,srsym,srsymtable);
  4822. if (srsym=nil) or
  4823. (srsym^.typ<>typesym) then
  4824. begin
  4825. Message(type_e_type_id_expected);
  4826. exit;
  4827. end;
  4828. typeglobalnumber := pstoreddef(ptypesym(srsym)^.restype.def)^.numberstring;
  4829. make_ref:=old_make_ref;
  4830. end;
  4831. {$endif GDB}
  4832. {****************************************************************************
  4833. Definition Helpers
  4834. ****************************************************************************}
  4835. procedure reset_global_defs;
  4836. var
  4837. def : pstoreddef;
  4838. {$ifdef debug}
  4839. prevdef : pstoreddef;
  4840. {$endif debug}
  4841. begin
  4842. {$ifdef debug}
  4843. prevdef:=nil;
  4844. {$endif debug}
  4845. {$ifdef GDB}
  4846. pglobaltypecount:=@globaltypecount;
  4847. {$endif GDB}
  4848. def:=firstglobaldef;
  4849. while assigned(def) do
  4850. begin
  4851. {$ifdef GDB}
  4852. if assigned(def^.typesym) then
  4853. ptypesym(def^.typesym)^.isusedinstab:=false;
  4854. def^.is_def_stab_written:=not_written;
  4855. {$endif GDB}
  4856. {if not current_module.in_implementation then}
  4857. begin
  4858. { reset rangenr's }
  4859. case def^.deftype of
  4860. orddef : porddef(def)^.rangenr:=0;
  4861. enumdef : penumdef(def)^.rangenr:=0;
  4862. arraydef : parraydef(def)^.rangenr:=0;
  4863. end;
  4864. if def^.deftype<>objectdef then
  4865. def^.has_rtti:=false;
  4866. def^.has_inittable:=false;
  4867. end;
  4868. {$ifdef debug}
  4869. prevdef:=def;
  4870. {$endif debug}
  4871. def:=def^.nextglobal;
  4872. end;
  4873. end;
  4874. function is_interfacecom(def: pdef): boolean;
  4875. begin
  4876. is_interfacecom:=
  4877. assigned(def) and
  4878. (def^.deftype=objectdef) and
  4879. (pobjectdef(def)^.objecttype=odt_interfacecom);
  4880. end;
  4881. function is_interfacecorba(def: pdef): boolean;
  4882. begin
  4883. is_interfacecorba:=
  4884. assigned(def) and
  4885. (def^.deftype=objectdef) and
  4886. (pobjectdef(def)^.objecttype=odt_interfacecorba);
  4887. end;
  4888. function is_interface(def: pdef): boolean;
  4889. begin
  4890. is_interface:=
  4891. assigned(def) and
  4892. (def^.deftype=objectdef) and
  4893. (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]);
  4894. end;
  4895. function is_class(def: pdef): boolean;
  4896. begin
  4897. is_class:=
  4898. assigned(def) and
  4899. (def^.deftype=objectdef) and
  4900. (pobjectdef(def)^.objecttype=odt_class);
  4901. end;
  4902. function is_object(def: pdef): boolean;
  4903. begin
  4904. is_object:=
  4905. assigned(def) and
  4906. (def^.deftype=objectdef) and
  4907. (pobjectdef(def)^.objecttype=odt_object);
  4908. end;
  4909. function is_cppclass(def: pdef): boolean;
  4910. begin
  4911. is_cppclass:=
  4912. assigned(def) and
  4913. (def^.deftype=objectdef) and
  4914. (pobjectdef(def)^.objecttype=odt_cppclass);
  4915. end;
  4916. function is_class_or_interface(def: pdef): boolean;
  4917. begin
  4918. is_class_or_interface:=
  4919. assigned(def) and
  4920. (def^.deftype=objectdef) and
  4921. (pobjectdef(def)^.objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4922. end;
  4923. end.
  4924. {
  4925. $Log$
  4926. Revision 1.23 2001-03-22 23:28:39 florian
  4927. * correct initialisation of rec_tguid when loading the system unit
  4928. Revision 1.22 2001/03/22 00:10:58 florian
  4929. + basic variant type support in the compiler
  4930. Revision 1.21 2001/03/11 22:58:50 peter
  4931. * getsym redesign, removed the globals srsym,srsymtable
  4932. Revision 1.20 2001/01/06 20:11:29 peter
  4933. * merged c packrecords fix
  4934. Revision 1.19 2000/12/25 00:07:29 peter
  4935. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  4936. tlinkedlist objects)
  4937. Revision 1.18 2000/12/24 12:20:45 peter
  4938. * classes, enum stabs fixes merged from 1.0.x
  4939. Revision 1.17 2000/12/07 17:19:43 jonas
  4940. * new constant handling: from now on, hex constants >$7fffffff are
  4941. parsed as unsigned constants (otherwise, $80000000 got sign extended
  4942. and became $ffffffff80000000), all constants in the longint range
  4943. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  4944. are cardinals and the rest are int64's.
  4945. * added lots of longint typecast to prevent range check errors in the
  4946. compiler and rtl
  4947. * type casts of symbolic ordinal constants are now preserved
  4948. * fixed bug where the original resulttype wasn't restored correctly
  4949. after doing a 64bit rangecheck
  4950. Revision 1.16 2000/11/30 23:12:57 florian
  4951. * if raw interfaces inherit from IUnknown they are ref. counted too
  4952. Revision 1.15 2000/11/29 00:30:40 florian
  4953. * unused units removed from uses clause
  4954. * some changes for widestrings
  4955. Revision 1.14 2000/11/28 00:28:06 pierre
  4956. * stabs fixing
  4957. Revision 1.13 2000/11/26 18:09:40 florian
  4958. * fixed rtti for chars
  4959. Revision 1.12 2000/11/19 16:23:35 florian
  4960. *** empty log message ***
  4961. Revision 1.11 2000/11/12 23:24:12 florian
  4962. * interfaces are basically running
  4963. Revision 1.10 2000/11/11 16:12:38 peter
  4964. * add far; to typename for far pointer
  4965. Revision 1.9 2000/11/07 20:01:57 peter
  4966. * fix vmt index for classes
  4967. Revision 1.8 2000/11/06 23:13:53 peter
  4968. * uppercase manglednames
  4969. Revision 1.7 2000/11/06 23:11:38 florian
  4970. * writeln debugger uninstalled ;)
  4971. Revision 1.6 2000/11/06 23:05:52 florian
  4972. * more fixes
  4973. Revision 1.5 2000/11/06 20:30:55 peter
  4974. * more fixes to get make cycle working
  4975. Revision 1.4 2000/11/04 14:25:22 florian
  4976. + merged Attila's changes for interfaces, not tested yet
  4977. Revision 1.3 2000/11/02 12:04:10 pierre
  4978. * remove RecOffset code, that created problems
  4979. Revision 1.2 2000/11/01 23:04:38 peter
  4980. * tprocdef.fullprocname added for better casesensitve writing of
  4981. procedures
  4982. Revision 1.1 2000/10/31 22:02:52 peter
  4983. * symtable splitted, no real code changes
  4984. }