symdef.pas 174 KB

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