symdef.pas 167 KB

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