symdef.pas 165 KB

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