symdef.pas 171 KB

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