symdef.pas 171 KB

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