symdef.pas 171 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symdef;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,globals,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,
  28. { ppu }
  29. symppu,ppu,
  30. { node }
  31. node,
  32. { aasm }
  33. aasm,cpubase
  34. ;
  35. type
  36. {************************************************
  37. TDef
  38. ************************************************}
  39. tstoreddef = class(tdef)
  40. { 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. paratyp : tvarspez;
  90. argconvtyp : targconvtyp;
  91. convertlevel : byte;
  92. register : tregister;
  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 : longint;
  336. typ : tbasetype;
  337. constructor create(t : tbasetype;v,b : longint);
  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;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. public
  419. extnumber : longint;
  420. messageinf : tmessageinf;
  421. {$ifndef EXTDEBUG}
  422. { where is this function defined, needed here because there
  423. is only one symbol for all overloaded functions
  424. EXTDEBUG has fileinfo in tdef (PFV) }
  425. fileinfo : tfileposinfo;
  426. {$endif}
  427. { symbol owning this definition }
  428. procsym : tsym;
  429. { alias names }
  430. aliasnames : tstringlist;
  431. { symtables }
  432. parast,
  433. localst : tsymtable;
  434. funcretsym : tsym;
  435. { next is only used to check if RESULT is accessed,
  436. not stored in a tnode }
  437. resultfuncretsym : tsym;
  438. { browser info }
  439. lastref,
  440. defref,
  441. crossref,
  442. lastwritten : tref;
  443. refcount : longint;
  444. _class : tobjectdef;
  445. { it's a tree, but this not easy to handle }
  446. { used for inlined procs }
  447. code : tnode;
  448. { info about register variables (JM) }
  449. regvarinfo: pointer;
  450. { true, if the procedure is only declared }
  451. { (forward procedure) }
  452. forwarddef,
  453. { true if the procedure is declared in the interface }
  454. interfacedef : boolean;
  455. { true if the procedure has a forward declaration }
  456. hasforward : boolean;
  457. { check the problems of manglednames }
  458. count : boolean;
  459. is_used : boolean;
  460. has_mangledname : boolean;
  461. { small set which contains the modified registers }
  462. {$ifdef i386}
  463. usedregisters : longint;
  464. {$endif}
  465. {$ifdef POWERPC}
  466. { not used, only a fake }
  467. usedregisters : longint;
  468. {$endif}
  469. constructor create;
  470. constructor load(ppufile:tcompilerppufile);
  471. destructor destroy;override;
  472. procedure write(ppufile:tcompilerppufile);override;
  473. procedure deref;override;
  474. procedure derefimpl;override;
  475. function getsymtable(t:tgetsymtable):tsymtable;override;
  476. function haspara:boolean;
  477. function mangledname : string;
  478. procedure setmangledname(const s : string);
  479. procedure load_references(ppufile:tcompilerppufile;locals:boolean);
  480. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  481. function fullprocname:string;
  482. function fullprocnamewithret:string;
  483. function cplusplusmangledname : string;
  484. { debug }
  485. {$ifdef GDB}
  486. function stabstring : pchar;override;
  487. procedure concatstabto(asmlist : taasmoutput);override;
  488. {$endif GDB}
  489. end;
  490. { single linked list of overloaded procs }
  491. pprocdeflist = ^tprocdeflist;
  492. tprocdeflist = record
  493. def : tprocdef;
  494. next : pprocdeflist;
  495. end;
  496. tstringdef = class(tstoreddef)
  497. string_typ : tstringtype;
  498. len : longint;
  499. constructor createshort(l : byte);
  500. constructor loadshort(ppufile:tcompilerppufile);
  501. constructor createlong(l : longint);
  502. constructor loadlong(ppufile:tcompilerppufile);
  503. constructor createansi(l : longint);
  504. constructor loadansi(ppufile:tcompilerppufile);
  505. constructor createwide(l : longint);
  506. constructor loadwide(ppufile:tcompilerppufile);
  507. function stringtypname:string;
  508. function size : longint;override;
  509. procedure write(ppufile:tcompilerppufile);override;
  510. function gettypename:string;override;
  511. function is_publishable : boolean;override;
  512. { debug }
  513. {$ifdef GDB}
  514. function stabstring : pchar;override;
  515. procedure concatstabto(asmlist : taasmoutput);override;
  516. {$endif GDB}
  517. { init/final }
  518. function needs_inittable : boolean;override;
  519. { rtti }
  520. procedure write_rtti_data(rt:trttitype);override;
  521. end;
  522. tenumdef = class(tstoreddef)
  523. rangenr,
  524. minval,
  525. maxval : longint;
  526. has_jumps : boolean;
  527. firstenum : tsym; {tenumsym}
  528. basedef : tenumdef;
  529. constructor create;
  530. constructor create_subrange(_basedef:tenumdef;_min,_max:longint);
  531. constructor load(ppufile:tcompilerppufile);
  532. destructor destroy;override;
  533. procedure write(ppufile:tcompilerppufile);override;
  534. procedure deref;override;
  535. function gettypename:string;override;
  536. function is_publishable : boolean;override;
  537. procedure calcsavesize;
  538. procedure setmax(_max:longint);
  539. procedure setmin(_min:longint);
  540. function min:longint;
  541. function max:longint;
  542. function getrangecheckstring:string;
  543. procedure genrangecheck;
  544. { debug }
  545. {$ifdef GDB}
  546. function stabstring : pchar;override;
  547. {$endif GDB}
  548. { rtti }
  549. procedure write_rtti_data(rt:trttitype);override;
  550. procedure write_child_rtti_data(rt:trttitype);override;
  551. private
  552. procedure correct_owner_symtable;
  553. end;
  554. tsetdef = class(tstoreddef)
  555. elementtype : ttype;
  556. settype : tsettype;
  557. constructor create(const t:ttype;high : longint);
  558. constructor load(ppufile:tcompilerppufile);
  559. destructor destroy;override;
  560. procedure write(ppufile:tcompilerppufile);override;
  561. procedure deref;override;
  562. function gettypename:string;override;
  563. function is_publishable : boolean;override;
  564. procedure changesettype(s:tsettype);
  565. { debug }
  566. {$ifdef GDB}
  567. function stabstring : pchar;override;
  568. procedure concatstabto(asmlist : taasmoutput);override;
  569. {$endif GDB}
  570. { rtti }
  571. procedure write_rtti_data(rt:trttitype);override;
  572. procedure write_child_rtti_data(rt:trttitype);override;
  573. end;
  574. var
  575. aktobjectdef : tobjectdef; { used for private functions check !! }
  576. firstglobaldef, { linked list of all globals defs }
  577. lastglobaldef : tstoreddef; { used to reset stabs/ranges }
  578. {$ifdef GDB}
  579. { for STAB debugging }
  580. globaltypecount : word;
  581. pglobaltypecount : pword;
  582. {$endif GDB}
  583. { default types }
  584. generrortype, { error in definition }
  585. voidpointertype, { pointer for Void-Pointerdef }
  586. charpointertype, { pointer for Char-Pointerdef }
  587. voidfarpointertype,
  588. cformaltype, { unique formal definition }
  589. voidtype, { Pointer to Void (procedure) }
  590. cchartype, { Pointer to Char }
  591. cwidechartype, { Pointer to WideChar }
  592. booltype, { pointer to boolean type }
  593. u8bittype, { Pointer to 8-Bit unsigned }
  594. u16bittype, { Pointer to 16-Bit unsigned }
  595. u32bittype, { Pointer to 32-Bit unsigned }
  596. s32bittype, { Pointer to 32-Bit signed }
  597. cu64bittype, { pointer to 64 bit unsigned def }
  598. cs64bittype, { pointer to 64 bit signed def, }
  599. s32floattype, { pointer for realconstn }
  600. s64floattype, { pointer for realconstn }
  601. s80floattype, { pointer to type of temp. floats }
  602. s32fixedtype, { pointer to type of temp. fixed }
  603. cshortstringtype, { pointer to type of short string const }
  604. clongstringtype, { pointer to type of long string const }
  605. cansistringtype, { pointer to type of ansi string const }
  606. cwidestringtype, { pointer to type of wide string const }
  607. openshortstringtype, { pointer to type of an open shortstring,
  608. needed for readln() }
  609. openchararraytype, { pointer to type of an open array of char,
  610. needed for readln() }
  611. cfiletype, { get the same definition for all file }
  612. { used for stabs }
  613. cvarianttype, { we use only one variant def }
  614. pvmttype : ttype; { type of classrefs, used for stabs }
  615. class_tobject : tobjectdef; { pointer to the anchestor of all classes }
  616. interface_iunknown : tobjectdef; { KAZ: pointer to the ancestor }
  617. rec_tguid : trecorddef; { KAZ: pointer to the TGUID type }
  618. { of all interfaces }
  619. const
  620. {$ifdef i386}
  621. pbestrealtype : ^ttype = @s80floattype;
  622. {$endif}
  623. {$ifdef m68k}
  624. pbestrealtype : ^ttype = @s64floattype;
  625. {$endif}
  626. {$ifdef alpha}
  627. pbestrealtype : ^ttype = @s64floattype;
  628. {$endif}
  629. {$ifdef powerpc}
  630. pbestrealtype : ^ttype = @s64floattype;
  631. {$endif}
  632. {$ifdef ia64}
  633. pbestrealtype : ^ttype = @s64floattype;
  634. {$endif}
  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,cpuinfo,
  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 : longint);
  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. begin
  1421. inherited loaddef(ppufile);
  1422. deftype:=orddef;
  1423. typ:=tbasetype(ppufile.getbyte);
  1424. low:=ppufile.getlongint;
  1425. high:=ppufile.getlongint;
  1426. rangenr:=0;
  1427. setsize;
  1428. end;
  1429. procedure torddef.setsize;
  1430. begin
  1431. if typ=uauto then
  1432. begin
  1433. { generate a unsigned range if high<0 and low>=0 }
  1434. if (low>=0) and (high<0) then
  1435. begin
  1436. savesize:=4;
  1437. typ:=u32bit;
  1438. end
  1439. else if (low>=0) and (high<=255) then
  1440. begin
  1441. savesize:=1;
  1442. typ:=u8bit;
  1443. end
  1444. else if (low>=-128) and (high<=127) then
  1445. begin
  1446. savesize:=1;
  1447. typ:=s8bit;
  1448. end
  1449. else if (low>=0) and (high<=65536) then
  1450. begin
  1451. savesize:=2;
  1452. typ:=u16bit;
  1453. end
  1454. else if (low>=-32768) and (high<=32767) then
  1455. begin
  1456. savesize:=2;
  1457. typ:=s16bit;
  1458. end
  1459. else
  1460. begin
  1461. savesize:=4;
  1462. typ:=s32bit;
  1463. end;
  1464. end
  1465. else
  1466. begin
  1467. case typ of
  1468. u8bit,s8bit,
  1469. uchar,bool8bit:
  1470. savesize:=1;
  1471. u16bit,s16bit,
  1472. bool16bit,uwidechar:
  1473. savesize:=2;
  1474. s32bit,u32bit,
  1475. bool32bit:
  1476. savesize:=4;
  1477. u64bit,s64bit:
  1478. savesize:=8;
  1479. else
  1480. savesize:=0;
  1481. end;
  1482. end;
  1483. { there are no entrys for range checking }
  1484. rangenr:=0;
  1485. end;
  1486. function torddef.getrangecheckstring : string;
  1487. begin
  1488. if (cs_create_smart in aktmoduleswitches) then
  1489. getrangecheckstring:='R_'+current_module.modulename^+tostr(rangenr)
  1490. else
  1491. getrangecheckstring:='R_'+tostr(rangenr);
  1492. end;
  1493. procedure torddef.genrangecheck;
  1494. var
  1495. rangechecksize : longint;
  1496. begin
  1497. if rangenr=0 then
  1498. begin
  1499. if low<=high then
  1500. rangechecksize:=8
  1501. else
  1502. rangechecksize:=16;
  1503. { generate two constant for bounds }
  1504. getlabelnr(rangenr);
  1505. if (cs_create_smart in aktmoduleswitches) then
  1506. dataSegment.concat(Tai_symbol.Createname_global(getrangecheckstring,rangechecksize))
  1507. else
  1508. dataSegment.concat(Tai_symbol.Createname(getrangecheckstring,rangechecksize));
  1509. if low<=high then
  1510. begin
  1511. dataSegment.concat(Tai_const.Create_32bit(low));
  1512. dataSegment.concat(Tai_const.Create_32bit(high));
  1513. end
  1514. { for u32bit we need two bounds }
  1515. else
  1516. begin
  1517. dataSegment.concat(Tai_const.Create_32bit(low));
  1518. dataSegment.concat(Tai_const.Create_32bit($7fffffff));
  1519. dataSegment.concat(Tai_const.Create_32bit(longint($80000000)));
  1520. dataSegment.concat(Tai_const.Create_32bit(high));
  1521. end;
  1522. end;
  1523. end;
  1524. procedure torddef.write(ppufile:tcompilerppufile);
  1525. begin
  1526. inherited writedef(ppufile);
  1527. ppufile.putbyte(byte(typ));
  1528. ppufile.putlongint(low);
  1529. ppufile.putlongint(high);
  1530. ppufile.writeentry(iborddef);
  1531. end;
  1532. {$ifdef GDB}
  1533. function torddef.stabstring : pchar;
  1534. begin
  1535. case typ of
  1536. uvoid : stabstring := strpnew(numberstring+';');
  1537. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  1538. {$ifdef Use_integer_types_for_boolean}
  1539. bool8bit,
  1540. bool16bit,
  1541. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  1542. {$else : not Use_integer_types_for_boolean}
  1543. bool8bit : stabstring := strpnew('-21;');
  1544. bool16bit : stabstring := strpnew('-22;');
  1545. bool32bit : stabstring := strpnew('-23;');
  1546. u64bit : stabstring := strpnew('-32;');
  1547. s64bit : stabstring := strpnew('-31;');
  1548. {$endif not Use_integer_types_for_boolean}
  1549. { u32bit : stabstring := strpnew('r'+
  1550. s32bittype^.numberstring+';0;-1;'); }
  1551. else
  1552. stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';'+tostr(low)+';'+tostr(high)+';');
  1553. end;
  1554. end;
  1555. {$endif GDB}
  1556. procedure torddef.write_rtti_data(rt:trttitype);
  1557. procedure dointeger;
  1558. const
  1559. trans : array[uchar..bool8bit] of byte =
  1560. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  1561. begin
  1562. write_rtti_name;
  1563. rttiList.concat(Tai_const.Create_8bit(byte(trans[typ])));
  1564. rttiList.concat(Tai_const.Create_32bit(low));
  1565. rttiList.concat(Tai_const.Create_32bit(high));
  1566. end;
  1567. begin
  1568. case typ of
  1569. s64bit :
  1570. begin
  1571. rttiList.concat(Tai_const.Create_8bit(tkInt64));
  1572. write_rtti_name;
  1573. { low }
  1574. rttiList.concat(Tai_const.Create_32bit($0));
  1575. rttiList.concat(Tai_const.Create_32bit($8000));
  1576. { high }
  1577. rttiList.concat(Tai_const.Create_32bit($ffff));
  1578. rttiList.concat(Tai_const.Create_32bit($7fff));
  1579. end;
  1580. u64bit :
  1581. begin
  1582. rttiList.concat(Tai_const.Create_8bit(tkQWord));
  1583. write_rtti_name;
  1584. { low }
  1585. rttiList.concat(Tai_const.Create_32bit($0));
  1586. rttiList.concat(Tai_const.Create_32bit($0));
  1587. { high }
  1588. rttiList.concat(Tai_const.Create_32bit($0));
  1589. rttiList.concat(Tai_const.Create_32bit($8000));
  1590. end;
  1591. bool8bit:
  1592. begin
  1593. rttiList.concat(Tai_const.Create_8bit(tkBool));
  1594. dointeger;
  1595. end;
  1596. uchar:
  1597. begin
  1598. rttiList.concat(Tai_const.Create_8bit(tkChar));
  1599. dointeger;
  1600. end;
  1601. uwidechar:
  1602. begin
  1603. rttiList.concat(Tai_const.Create_8bit(tkWChar));
  1604. dointeger;
  1605. end;
  1606. else
  1607. begin
  1608. rttiList.concat(Tai_const.Create_8bit(tkInteger));
  1609. dointeger;
  1610. end;
  1611. end;
  1612. end;
  1613. function torddef.is_publishable : boolean;
  1614. begin
  1615. is_publishable:=typ in [uchar..bool8bit];
  1616. end;
  1617. function torddef.gettypename : string;
  1618. const
  1619. names : array[tbasetype] of string[20] = ('<unknown type>',
  1620. 'untyped','Char','Byte','Word','DWord','ShortInt',
  1621. 'SmallInt','LongInt','Boolean','WordBool',
  1622. 'LongBool','QWord','Int64','WideChar');
  1623. begin
  1624. gettypename:=names[typ];
  1625. end;
  1626. {****************************************************************************
  1627. TFLOATDEF
  1628. ****************************************************************************}
  1629. constructor tfloatdef.create(t : tfloattype);
  1630. begin
  1631. inherited create;
  1632. deftype:=floatdef;
  1633. typ:=t;
  1634. setsize;
  1635. end;
  1636. constructor tfloatdef.load(ppufile:tcompilerppufile);
  1637. begin
  1638. inherited loaddef(ppufile);
  1639. deftype:=floatdef;
  1640. typ:=tfloattype(ppufile.getbyte);
  1641. setsize;
  1642. end;
  1643. procedure tfloatdef.setsize;
  1644. begin
  1645. case typ of
  1646. s32real : savesize:=4;
  1647. s64real : savesize:=8;
  1648. s80real : savesize:=extended_size;
  1649. s64comp : savesize:=8;
  1650. else
  1651. savesize:=0;
  1652. end;
  1653. end;
  1654. procedure tfloatdef.write(ppufile:tcompilerppufile);
  1655. begin
  1656. inherited writedef(ppufile);
  1657. ppufile.putbyte(byte(typ));
  1658. ppufile.writeentry(ibfloatdef);
  1659. end;
  1660. {$ifdef GDB}
  1661. function tfloatdef.stabstring : pchar;
  1662. begin
  1663. case typ of
  1664. s32real,
  1665. s64real : stabstring := strpnew('r'+
  1666. tstoreddef(s32bittype.def).numberstring+';'+tostr(savesize)+';0;');
  1667. { found this solution in stabsread.c from GDB v4.16 }
  1668. s64comp : stabstring := strpnew('r'+
  1669. tstoreddef(s32bittype.def).numberstring+';-'+tostr(savesize)+';0;');
  1670. { under dos at least you must give a size of twelve instead of 10 !! }
  1671. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1672. s80real : stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';12;0;');
  1673. else
  1674. internalerror(10005);
  1675. end;
  1676. end;
  1677. {$endif GDB}
  1678. procedure tfloatdef.write_rtti_data(rt:trttitype);
  1679. const
  1680. {tfloattype = (s32real,s64real,s80real,s64bit);}
  1681. translate : array[tfloattype] of byte =
  1682. (ftSingle,ftDouble,ftExtended,ftComp);
  1683. begin
  1684. rttiList.concat(Tai_const.Create_8bit(tkFloat));
  1685. write_rtti_name;
  1686. rttiList.concat(Tai_const.Create_8bit(translate[typ]));
  1687. end;
  1688. function tfloatdef.is_publishable : boolean;
  1689. begin
  1690. is_publishable:=true;
  1691. end;
  1692. function tfloatdef.gettypename : string;
  1693. const
  1694. names : array[tfloattype] of string[20] = (
  1695. 'Single','Double','Extended','Comp');
  1696. begin
  1697. gettypename:=names[typ];
  1698. end;
  1699. {****************************************************************************
  1700. TFILEDEF
  1701. ****************************************************************************}
  1702. constructor tfiledef.createtext;
  1703. begin
  1704. inherited create;
  1705. deftype:=filedef;
  1706. filetyp:=ft_text;
  1707. typedfiletype.reset;
  1708. setsize;
  1709. end;
  1710. constructor tfiledef.createuntyped;
  1711. begin
  1712. inherited create;
  1713. deftype:=filedef;
  1714. filetyp:=ft_untyped;
  1715. typedfiletype.reset;
  1716. setsize;
  1717. end;
  1718. constructor tfiledef.createtyped(const tt : ttype);
  1719. begin
  1720. inherited create;
  1721. deftype:=filedef;
  1722. filetyp:=ft_typed;
  1723. typedfiletype:=tt;
  1724. setsize;
  1725. end;
  1726. constructor tfiledef.load(ppufile:tcompilerppufile);
  1727. begin
  1728. inherited loaddef(ppufile);
  1729. deftype:=filedef;
  1730. filetyp:=tfiletyp(ppufile.getbyte);
  1731. if filetyp=ft_typed then
  1732. ppufile.gettype(typedfiletype)
  1733. else
  1734. typedfiletype.reset;
  1735. setsize;
  1736. end;
  1737. procedure tfiledef.deref;
  1738. begin
  1739. inherited deref;
  1740. if filetyp=ft_typed then
  1741. typedfiletype.resolve;
  1742. end;
  1743. procedure tfiledef.setsize;
  1744. begin
  1745. case filetyp of
  1746. ft_text :
  1747. savesize:=572;
  1748. ft_typed,
  1749. ft_untyped :
  1750. savesize:=316;
  1751. end;
  1752. end;
  1753. procedure tfiledef.write(ppufile:tcompilerppufile);
  1754. begin
  1755. inherited writedef(ppufile);
  1756. ppufile.putbyte(byte(filetyp));
  1757. if filetyp=ft_typed then
  1758. ppufile.puttype(typedfiletype);
  1759. ppufile.writeentry(ibfiledef);
  1760. end;
  1761. {$ifdef GDB}
  1762. function tfiledef.stabstring : pchar;
  1763. begin
  1764. {$IfDef GDBknowsfiles}
  1765. case filetyp of
  1766. ft_typed :
  1767. stabstring := strpnew('d'+typedfiletype.def.numberstring{+';'});
  1768. ft_untyped :
  1769. stabstring := strpnew('d'+voiddef.numberstring{+';'});
  1770. ft_text :
  1771. stabstring := strpnew('d'+cchartype^.numberstring{+';'});
  1772. end;
  1773. {$Else}
  1774. {based on
  1775. FileRec = Packed Record
  1776. Handle,
  1777. Mode,
  1778. RecSize : longint;
  1779. _private : array[1..32] of byte;
  1780. UserData : array[1..16] of byte;
  1781. name : array[0..255] of char;
  1782. End; }
  1783. { the buffer part is still missing !! (PM) }
  1784. { but the string could become too long !! }
  1785. stabstring := strpnew('s'+tostr(savesize)+
  1786. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1787. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1788. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1789. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1790. +',96,256;'+
  1791. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1792. +',352,128;'+
  1793. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1794. +',480,2048;;');
  1795. {$EndIf}
  1796. end;
  1797. procedure tfiledef.concatstabto(asmlist : taasmoutput);
  1798. begin
  1799. { most file defs are unnamed !!! }
  1800. if ((typesym = nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1801. (is_def_stab_written = not_written) then
  1802. begin
  1803. if assigned(typedfiletype.def) then
  1804. forcestabto(asmlist,typedfiletype.def);
  1805. inherited concatstabto(asmlist);
  1806. end;
  1807. end;
  1808. {$endif GDB}
  1809. function tfiledef.gettypename : string;
  1810. begin
  1811. case filetyp of
  1812. ft_untyped:
  1813. gettypename:='File';
  1814. ft_typed:
  1815. gettypename:='File Of '+typedfiletype.def.typename;
  1816. ft_text:
  1817. gettypename:='Text'
  1818. end;
  1819. end;
  1820. {****************************************************************************
  1821. TVARIANTDEF
  1822. ****************************************************************************}
  1823. constructor tvariantdef.create;
  1824. begin
  1825. inherited create;
  1826. deftype:=variantdef;
  1827. setsize;
  1828. end;
  1829. constructor tvariantdef.load(ppufile:tcompilerppufile);
  1830. begin
  1831. inherited loaddef(ppufile);
  1832. deftype:=variantdef;
  1833. setsize;
  1834. end;
  1835. procedure tvariantdef.write(ppufile:tcompilerppufile);
  1836. begin
  1837. inherited writedef(ppufile);
  1838. ppufile.writeentry(ibvariantdef);
  1839. end;
  1840. procedure tvariantdef.setsize;
  1841. begin
  1842. savesize:=16;
  1843. end;
  1844. function tvariantdef.gettypename : string;
  1845. begin
  1846. gettypename:='Variant';
  1847. end;
  1848. procedure tvariantdef.write_rtti_data(rt:trttitype);
  1849. begin
  1850. rttiList.concat(Tai_const.Create_8bit(tkVariant));
  1851. end;
  1852. function tvariantdef.needs_inittable : boolean;
  1853. begin
  1854. needs_inittable:=true;
  1855. end;
  1856. {****************************************************************************
  1857. TPOINTERDEF
  1858. ****************************************************************************}
  1859. constructor tpointerdef.create(const tt : ttype);
  1860. begin
  1861. inherited create;
  1862. deftype:=pointerdef;
  1863. pointertype:=tt;
  1864. is_far:=false;
  1865. savesize:=target_info.size_of_pointer;
  1866. end;
  1867. constructor tpointerdef.createfar(const tt : ttype);
  1868. begin
  1869. inherited create;
  1870. deftype:=pointerdef;
  1871. pointertype:=tt;
  1872. is_far:=true;
  1873. savesize:=target_info.size_of_pointer;
  1874. end;
  1875. constructor tpointerdef.load(ppufile:tcompilerppufile);
  1876. begin
  1877. inherited loaddef(ppufile);
  1878. deftype:=pointerdef;
  1879. ppufile.gettype(pointertype);
  1880. is_far:=(ppufile.getbyte<>0);
  1881. savesize:=target_info.size_of_pointer;
  1882. end;
  1883. procedure tpointerdef.deref;
  1884. begin
  1885. inherited deref;
  1886. pointertype.resolve;
  1887. end;
  1888. procedure tpointerdef.write(ppufile:tcompilerppufile);
  1889. begin
  1890. inherited writedef(ppufile);
  1891. ppufile.puttype(pointertype);
  1892. ppufile.putbyte(byte(is_far));
  1893. ppufile.writeentry(ibpointerdef);
  1894. end;
  1895. {$ifdef GDB}
  1896. function tpointerdef.stabstring : pchar;
  1897. begin
  1898. stabstring := strpnew('*'+tstoreddef(pointertype.def).numberstring);
  1899. end;
  1900. procedure tpointerdef.concatstabto(asmlist : taasmoutput);
  1901. var st,nb : string;
  1902. sym_line_no : longint;
  1903. begin
  1904. if assigned(pointertype.def) and
  1905. (pointertype.def.deftype=forwarddef) then
  1906. exit;
  1907. if ( (typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1908. (is_def_stab_written = not_written) then
  1909. begin
  1910. is_def_stab_written := being_written;
  1911. if assigned(pointertype.def) and
  1912. (pointertype.def.deftype in [recorddef,objectdef]) then
  1913. begin
  1914. nb:=tstoreddef(pointertype.def).numberstring;
  1915. {to avoid infinite recursion in record with next-like fields }
  1916. if tstoreddef(pointertype.def).is_def_stab_written = being_written then
  1917. begin
  1918. if assigned(pointertype.def.typesym) then
  1919. begin
  1920. if assigned(typesym) then
  1921. begin
  1922. st := ttypesym(typesym).name;
  1923. sym_line_no:=ttypesym(typesym).fileinfo.line;
  1924. end
  1925. else
  1926. begin
  1927. st := ' ';
  1928. sym_line_no:=0;
  1929. end;
  1930. st := '"'+st+':t'+numberstring+'=*'+nb
  1931. +'=xs'+pointertype.def.typesym.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1932. asmList.concat(Tai_stabs.Create(strpnew(st)));
  1933. end;
  1934. end
  1935. else
  1936. begin
  1937. is_def_stab_written := not_written;
  1938. inherited concatstabto(asmlist);
  1939. end;
  1940. is_def_stab_written := written;
  1941. end
  1942. else
  1943. begin
  1944. if assigned(pointertype.def) then
  1945. forcestabto(asmlist,pointertype.def);
  1946. is_def_stab_written := not_written;
  1947. inherited concatstabto(asmlist);
  1948. end;
  1949. end;
  1950. end;
  1951. {$endif GDB}
  1952. function tpointerdef.gettypename : string;
  1953. begin
  1954. if is_far then
  1955. gettypename:='^'+pointertype.def.typename+';far'
  1956. else
  1957. gettypename:='^'+pointertype.def.typename;
  1958. end;
  1959. {****************************************************************************
  1960. TCLASSREFDEF
  1961. ****************************************************************************}
  1962. constructor tclassrefdef.create(const t:ttype);
  1963. begin
  1964. inherited create(t);
  1965. deftype:=classrefdef;
  1966. end;
  1967. constructor tclassrefdef.load(ppufile:tcompilerppufile);
  1968. begin
  1969. { be careful, tclassdefref inherits from tpointerdef }
  1970. inherited loaddef(ppufile);
  1971. deftype:=classrefdef;
  1972. ppufile.gettype(pointertype);
  1973. is_far:=false;
  1974. savesize:=target_info.size_of_pointer;
  1975. end;
  1976. procedure tclassrefdef.write(ppufile:tcompilerppufile);
  1977. begin
  1978. { be careful, tclassdefref inherits from tpointerdef }
  1979. inherited writedef(ppufile);
  1980. ppufile.puttype(pointertype);
  1981. ppufile.writeentry(ibclassrefdef);
  1982. end;
  1983. {$ifdef GDB}
  1984. function tclassrefdef.stabstring : pchar;
  1985. begin
  1986. stabstring:=strpnew(tstoreddef(pvmttype.def).numberstring+';');
  1987. end;
  1988. procedure tclassrefdef.concatstabto(asmlist : taasmoutput);
  1989. begin
  1990. inherited concatstabto(asmlist);
  1991. end;
  1992. {$endif GDB}
  1993. function tclassrefdef.gettypename : string;
  1994. begin
  1995. gettypename:='Class Of '+pointertype.def.typename;
  1996. end;
  1997. {***************************************************************************
  1998. TSETDEF
  1999. ***************************************************************************}
  2000. constructor tsetdef.create(const t:ttype;high : longint);
  2001. begin
  2002. inherited create;
  2003. deftype:=setdef;
  2004. elementtype:=t;
  2005. if high<32 then
  2006. begin
  2007. settype:=smallset;
  2008. {$ifdef testvarsets}
  2009. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  2010. {$endif}
  2011. savesize:=Sizeof(longint)
  2012. {$ifdef testvarsets}
  2013. else {No, use $PACKSET VALUE for rounding}
  2014. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  2015. {$endif}
  2016. ;
  2017. end
  2018. else
  2019. if high<256 then
  2020. begin
  2021. settype:=normset;
  2022. savesize:=32;
  2023. end
  2024. else
  2025. {$ifdef testvarsets}
  2026. if high<$10000 then
  2027. begin
  2028. settype:=varset;
  2029. savesize:=4*((high+31) div 32);
  2030. end
  2031. else
  2032. {$endif testvarsets}
  2033. Message(sym_e_ill_type_decl_set);
  2034. end;
  2035. constructor tsetdef.load(ppufile:tcompilerppufile);
  2036. begin
  2037. inherited loaddef(ppufile);
  2038. deftype:=setdef;
  2039. ppufile.gettype(elementtype);
  2040. settype:=tsettype(ppufile.getbyte);
  2041. case settype of
  2042. normset : savesize:=32;
  2043. varset : savesize:=ppufile.getlongint;
  2044. smallset : savesize:=Sizeof(longint);
  2045. end;
  2046. end;
  2047. destructor tsetdef.destroy;
  2048. begin
  2049. inherited destroy;
  2050. end;
  2051. procedure tsetdef.write(ppufile:tcompilerppufile);
  2052. begin
  2053. inherited writedef(ppufile);
  2054. ppufile.puttype(elementtype);
  2055. ppufile.putbyte(byte(settype));
  2056. if settype=varset then
  2057. ppufile.putlongint(savesize);
  2058. ppufile.writeentry(ibsetdef);
  2059. end;
  2060. procedure tsetdef.changesettype(s:tsettype);
  2061. begin
  2062. case s of
  2063. smallset :
  2064. savesize:=sizeof(longint);
  2065. normset :
  2066. savesize:=32;
  2067. varset :
  2068. internalerror(200110201);
  2069. end;
  2070. settype:=s;
  2071. end;
  2072. {$ifdef GDB}
  2073. function tsetdef.stabstring : pchar;
  2074. begin
  2075. { For small sets write a longint, which can at least be seen
  2076. in the current GDB's (PFV)
  2077. this is obsolete with GDBPAS !!
  2078. and anyhow creates problems with version 4.18!! PM
  2079. if settype=smallset then
  2080. stabstring := strpnew('r'+s32bittype^.numberstring+';0;0xffffffff;')
  2081. else }
  2082. stabstring := strpnew('S'+tstoreddef(elementtype.def).numberstring);
  2083. end;
  2084. procedure tsetdef.concatstabto(asmlist : taasmoutput);
  2085. begin
  2086. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2087. (is_def_stab_written = not_written) then
  2088. begin
  2089. if assigned(elementtype.def) then
  2090. forcestabto(asmlist,elementtype.def);
  2091. inherited concatstabto(asmlist);
  2092. end;
  2093. end;
  2094. {$endif GDB}
  2095. procedure tsetdef.deref;
  2096. begin
  2097. inherited deref;
  2098. elementtype.resolve;
  2099. end;
  2100. procedure tsetdef.write_child_rtti_data(rt:trttitype);
  2101. begin
  2102. tstoreddef(elementtype.def).get_rtti_label(rt);
  2103. end;
  2104. procedure tsetdef.write_rtti_data(rt:trttitype);
  2105. begin
  2106. rttiList.concat(Tai_const.Create_8bit(tkSet));
  2107. write_rtti_name;
  2108. rttiList.concat(Tai_const.Create_8bit(otULong));
  2109. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2110. end;
  2111. function tsetdef.is_publishable : boolean;
  2112. begin
  2113. is_publishable:=(settype=smallset);
  2114. end;
  2115. function tsetdef.gettypename : string;
  2116. begin
  2117. if assigned(elementtype.def) then
  2118. gettypename:='Set Of '+elementtype.def.typename
  2119. else
  2120. gettypename:='Empty Set';
  2121. end;
  2122. {***************************************************************************
  2123. TFORMALDEF
  2124. ***************************************************************************}
  2125. constructor tformaldef.create;
  2126. var
  2127. stregdef : boolean;
  2128. begin
  2129. stregdef:=registerdef;
  2130. registerdef:=false;
  2131. inherited create;
  2132. deftype:=formaldef;
  2133. registerdef:=stregdef;
  2134. { formaldef must be registered at unit level !! }
  2135. if registerdef and assigned(current_module) then
  2136. if assigned(current_module.localsymtable) then
  2137. tsymtable(current_module.localsymtable).registerdef(self)
  2138. else if assigned(current_module.globalsymtable) then
  2139. tsymtable(current_module.globalsymtable).registerdef(self);
  2140. savesize:=target_info.size_of_pointer;
  2141. end;
  2142. constructor tformaldef.load(ppufile:tcompilerppufile);
  2143. begin
  2144. inherited loaddef(ppufile);
  2145. deftype:=formaldef;
  2146. savesize:=target_info.size_of_pointer;
  2147. end;
  2148. procedure tformaldef.write(ppufile:tcompilerppufile);
  2149. begin
  2150. inherited writedef(ppufile);
  2151. ppufile.writeentry(ibformaldef);
  2152. end;
  2153. {$ifdef GDB}
  2154. function tformaldef.stabstring : pchar;
  2155. begin
  2156. stabstring := strpnew('formal'+numberstring+';');
  2157. end;
  2158. procedure tformaldef.concatstabto(asmlist : taasmoutput);
  2159. begin
  2160. { formaldef can't be stab'ed !}
  2161. end;
  2162. {$endif GDB}
  2163. function tformaldef.gettypename : string;
  2164. begin
  2165. gettypename:='Var';
  2166. end;
  2167. {***************************************************************************
  2168. TARRAYDEF
  2169. ***************************************************************************}
  2170. constructor tarraydef.create(l,h : longint;const t : ttype);
  2171. begin
  2172. inherited create;
  2173. deftype:=arraydef;
  2174. lowrange:=l;
  2175. highrange:=h;
  2176. rangetype:=t;
  2177. elementtype.reset;
  2178. IsVariant:=false;
  2179. IsConstructor:=false;
  2180. IsArrayOfConst:=false;
  2181. IsDynamicArray:=false;
  2182. rangenr:=0;
  2183. end;
  2184. constructor tarraydef.load(ppufile:tcompilerppufile);
  2185. begin
  2186. inherited loaddef(ppufile);
  2187. deftype:=arraydef;
  2188. { the addresses are calculated later }
  2189. ppufile.gettype(elementtype);
  2190. ppufile.gettype(rangetype);
  2191. lowrange:=ppufile.getlongint;
  2192. highrange:=ppufile.getlongint;
  2193. IsArrayOfConst:=boolean(ppufile.getbyte);
  2194. IsDynamicArray:=boolean(ppufile.getbyte);
  2195. IsVariant:=false;
  2196. IsConstructor:=false;
  2197. rangenr:=0;
  2198. end;
  2199. function tarraydef.getrangecheckstring : string;
  2200. begin
  2201. if (cs_create_smart in aktmoduleswitches) then
  2202. getrangecheckstring:='R_'+current_module.modulename^+tostr(rangenr)
  2203. else
  2204. getrangecheckstring:='R_'+tostr(rangenr);
  2205. end;
  2206. procedure tarraydef.genrangecheck;
  2207. begin
  2208. if rangenr=0 then
  2209. begin
  2210. { generates the data for range checking }
  2211. getlabelnr(rangenr);
  2212. if (cs_create_smart in aktmoduleswitches) then
  2213. dataSegment.concat(Tai_symbol.Createname_global(getrangecheckstring,8))
  2214. else
  2215. dataSegment.concat(Tai_symbol.Createname(getrangecheckstring,8));
  2216. if lowrange<=highrange then
  2217. begin
  2218. dataSegment.concat(Tai_const.Create_32bit(lowrange));
  2219. dataSegment.concat(Tai_const.Create_32bit(highrange));
  2220. end
  2221. { for big arrays we need two bounds }
  2222. else
  2223. begin
  2224. dataSegment.concat(Tai_const.Create_32bit(lowrange));
  2225. dataSegment.concat(Tai_const.Create_32bit($7fffffff));
  2226. dataSegment.concat(Tai_const.Create_32bit(longint($80000000)));
  2227. dataSegment.concat(Tai_const.Create_32bit(highrange));
  2228. end;
  2229. end;
  2230. end;
  2231. procedure tarraydef.deref;
  2232. begin
  2233. inherited deref;
  2234. elementtype.resolve;
  2235. rangetype.resolve;
  2236. end;
  2237. procedure tarraydef.write(ppufile:tcompilerppufile);
  2238. begin
  2239. inherited writedef(ppufile);
  2240. ppufile.puttype(elementtype);
  2241. ppufile.puttype(rangetype);
  2242. ppufile.putlongint(lowrange);
  2243. ppufile.putlongint(highrange);
  2244. ppufile.putbyte(byte(IsArrayOfConst));
  2245. ppufile.putbyte(byte(IsDynamicArray));
  2246. ppufile.writeentry(ibarraydef);
  2247. end;
  2248. {$ifdef GDB}
  2249. function tarraydef.stabstring : pchar;
  2250. begin
  2251. stabstring := strpnew('ar'+tstoreddef(rangetype.def).numberstring+';'
  2252. +tostr(lowrange)+';'+tostr(highrange)+';'+tstoreddef(elementtype.def).numberstring);
  2253. end;
  2254. procedure tarraydef.concatstabto(asmlist : taasmoutput);
  2255. begin
  2256. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2257. and (is_def_stab_written = not_written) then
  2258. begin
  2259. {when array are inserted they have no definition yet !!}
  2260. if assigned(elementtype.def) then
  2261. inherited concatstabto(asmlist);
  2262. end;
  2263. end;
  2264. {$endif GDB}
  2265. function tarraydef.elesize : longint;
  2266. begin
  2267. elesize:=elementtype.def.size;
  2268. end;
  2269. function tarraydef.size : longint;
  2270. begin
  2271. if IsDynamicArray then
  2272. begin
  2273. size:=4;
  2274. exit;
  2275. end;
  2276. {Tarraydef.size may never be called for an open array!}
  2277. if highrange<lowrange then
  2278. internalerror(99080501);
  2279. If (elesize>0) and
  2280. (
  2281. (int64(highrange)-int64(lowrange) >= $7fffffff) or
  2282. { () are needed around elesize-1 to avoid a possible
  2283. integer overflow for elesize=1 !! PM }
  2284. (($7fffffff div elesize + (elesize -1)) < (int64(highrange) - int64(lowrange)))
  2285. ) Then
  2286. Begin
  2287. Message(sym_e_segment_too_large);
  2288. size := 4
  2289. End
  2290. Else size:=(highrange-lowrange+1)*elesize;
  2291. end;
  2292. function tarraydef.alignment : longint;
  2293. begin
  2294. { alignment is the size of the elements }
  2295. if elementtype.def.deftype=recorddef then
  2296. alignment:=elementtype.def.alignment
  2297. else
  2298. alignment:=elesize;
  2299. end;
  2300. function tarraydef.needs_inittable : boolean;
  2301. begin
  2302. needs_inittable:=IsDynamicArray or elementtype.def.needs_inittable;
  2303. end;
  2304. procedure tarraydef.write_child_rtti_data(rt:trttitype);
  2305. begin
  2306. tstoreddef(elementtype.def).get_rtti_label(rt);
  2307. end;
  2308. procedure tarraydef.write_rtti_data(rt:trttitype);
  2309. begin
  2310. if IsDynamicArray then
  2311. rttiList.concat(Tai_const.Create_8bit(tkdynarray))
  2312. else
  2313. rttiList.concat(Tai_const.Create_8bit(tkarray));
  2314. write_rtti_name;
  2315. { size of elements }
  2316. rttiList.concat(Tai_const.Create_32bit(elesize));
  2317. { count of elements }
  2318. if not(IsDynamicArray) then
  2319. rttiList.concat(Tai_const.Create_32bit(highrange-lowrange+1));
  2320. { element type }
  2321. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2322. { variant type }
  2323. // !!!!!!!!!!!!!!!!
  2324. end;
  2325. function tarraydef.gettypename : string;
  2326. begin
  2327. if isarrayofconst or isConstructor then
  2328. begin
  2329. if isvariant or ((highrange=-1) and (lowrange=0)) then
  2330. gettypename:='Array Of Const'
  2331. else
  2332. gettypename:='Array Of '+elementtype.def.typename;
  2333. end
  2334. else if ((highrange=-1) and (lowrange=0)) or IsDynamicArray then
  2335. gettypename:='Array Of '+elementtype.def.typename
  2336. else
  2337. begin
  2338. if rangetype.def.deftype=enumdef then
  2339. gettypename:='Array['+rangetype.def.typename+'] Of '+elementtype.def.typename
  2340. else
  2341. gettypename:='Array['+tostr(lowrange)+'..'+
  2342. tostr(highrange)+'] Of '+elementtype.def.typename
  2343. end;
  2344. end;
  2345. {***************************************************************************
  2346. tabstractrecorddef
  2347. ***************************************************************************}
  2348. function tabstractrecorddef.getsymtable(t:tgetsymtable):tsymtable;
  2349. begin
  2350. if t=gs_record then
  2351. getsymtable:=symtable
  2352. else
  2353. getsymtable:=nil;
  2354. end;
  2355. {$ifdef GDB}
  2356. procedure tabstractrecorddef.addname(p : tnamedindexitem);
  2357. var
  2358. news, newrec : pchar;
  2359. spec : string[3];
  2360. varsize : longint;
  2361. begin
  2362. { static variables from objects are like global objects }
  2363. if (sp_static in tsym(p).symoptions) then
  2364. exit;
  2365. If tsym(p).typ = varsym then
  2366. begin
  2367. if (sp_protected in tsym(p).symoptions) then
  2368. spec:='/1'
  2369. else if (sp_private in tsym(p).symoptions) then
  2370. spec:='/0'
  2371. else
  2372. spec:='';
  2373. if not assigned(tvarsym(p).vartype.def) then
  2374. writeln(tvarsym(p).name);
  2375. { class fields are pointers PM, obsolete now PM }
  2376. {if (tvarsym(p).vartype.def.deftype=objectdef) and
  2377. tobjectdef(tvarsym(p).vartype.def).is_class then
  2378. spec:=spec+'*'; }
  2379. varsize:=tvarsym(p).vartype.def.size;
  2380. { open arrays made overflows !! }
  2381. if varsize>$fffffff then
  2382. varsize:=$fffffff;
  2383. newrec := strpnew(p.name+':'+spec+tstoreddef(tvarsym(p).vartype.def).numberstring
  2384. +','+tostr(tvarsym(p).address*8)+','
  2385. +tostr(varsize*8)+';');
  2386. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2387. begin
  2388. getmem(news,stabrecsize+memsizeinc);
  2389. strcopy(news,stabrecstring);
  2390. freemem(stabrecstring,stabrecsize);
  2391. stabrecsize:=stabrecsize+memsizeinc;
  2392. stabrecstring:=news;
  2393. end;
  2394. strcat(StabRecstring,newrec);
  2395. strdispose(newrec);
  2396. {This should be used for case !!}
  2397. inc(RecOffset,tvarsym(p).vartype.def.size);
  2398. end;
  2399. end;
  2400. {$endif GDB}
  2401. procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem);
  2402. begin
  2403. if (FRTTIType=fullrtti) or
  2404. ((tsym(sym).typ=varsym) and
  2405. tvarsym(sym).vartype.def.needs_inittable) then
  2406. inc(Count);
  2407. end;
  2408. procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem);
  2409. begin
  2410. if (FRTTIType=fullrtti) or
  2411. ((tsym(sym).typ=varsym) and
  2412. tvarsym(sym).vartype.def.needs_inittable) then
  2413. tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType);
  2414. end;
  2415. procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem);
  2416. begin
  2417. if (FRTTIType=fullrtti) or
  2418. ((tsym(sym).typ=varsym) and
  2419. tvarsym(sym).vartype.def.needs_inittable) then
  2420. begin
  2421. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType)));
  2422. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  2423. end;
  2424. end;
  2425. {***************************************************************************
  2426. trecorddef
  2427. ***************************************************************************}
  2428. constructor trecorddef.create(p : tsymtable);
  2429. begin
  2430. inherited create;
  2431. deftype:=recorddef;
  2432. symtable:=p;
  2433. symtable.defowner:=self;
  2434. { recordalign -1 means C record packing, that starts
  2435. with an alignment of 1 }
  2436. if aktalignment.recordalignmax=-1 then
  2437. symtable.dataalignment:=1
  2438. else
  2439. symtable.dataalignment:=aktalignment.recordalignmax;
  2440. end;
  2441. constructor trecorddef.load(ppufile:tcompilerppufile);
  2442. var
  2443. oldread_member : boolean;
  2444. begin
  2445. inherited loaddef(ppufile);
  2446. deftype:=recorddef;
  2447. savesize:=ppufile.getlongint;
  2448. oldread_member:=read_member;
  2449. read_member:=true;
  2450. symtable:=trecordsymtable.create;
  2451. trecordsymtable(symtable).load(ppufile);
  2452. read_member:=oldread_member;
  2453. symtable.defowner:=self;
  2454. end;
  2455. destructor trecorddef.destroy;
  2456. begin
  2457. if assigned(symtable) then
  2458. symtable.free;
  2459. inherited destroy;
  2460. end;
  2461. function trecorddef.needs_inittable : boolean;
  2462. begin
  2463. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2464. end;
  2465. procedure trecorddef.deref;
  2466. var
  2467. oldrecsyms : tsymtable;
  2468. begin
  2469. inherited deref;
  2470. oldrecsyms:=aktrecordsymtable;
  2471. aktrecordsymtable:=symtable;
  2472. { now dereference the definitions }
  2473. tstoredsymtable(symtable).deref;
  2474. aktrecordsymtable:=oldrecsyms;
  2475. { assign TGUID? load only from system unit (unitid=1) }
  2476. if not(assigned(rec_tguid)) and
  2477. (upper(typename)='TGUID') and
  2478. assigned(owner) and
  2479. assigned(owner.name) and
  2480. (owner.name^='SYSTEM') then
  2481. rec_tguid:=self;
  2482. end;
  2483. procedure trecorddef.write(ppufile:tcompilerppufile);
  2484. var
  2485. oldread_member : boolean;
  2486. begin
  2487. oldread_member:=read_member;
  2488. read_member:=true;
  2489. inherited writedef(ppufile);
  2490. ppufile.putlongint(savesize);
  2491. ppufile.writeentry(ibrecorddef);
  2492. trecordsymtable(symtable).write(ppufile);
  2493. read_member:=oldread_member;
  2494. end;
  2495. function trecorddef.size:longint;
  2496. begin
  2497. size:=symtable.datasize;
  2498. end;
  2499. function trecorddef.alignment:longint;
  2500. var
  2501. l : longint;
  2502. hp : tvarsym;
  2503. begin
  2504. { also check the first symbol for it's size, because a
  2505. packed record has dataalignment of 1, but the first
  2506. sym could be a longint which should be aligned on 4 bytes,
  2507. this is compatible with C record packing (PFV) }
  2508. hp:=tvarsym(symtable.symindex.first);
  2509. if assigned(hp) then
  2510. begin
  2511. if hp.vartype.def.deftype in [recorddef,arraydef] then
  2512. l:=hp.vartype.def.alignment
  2513. else
  2514. l:=hp.vartype.def.size;
  2515. if l>symtable.dataalignment then
  2516. begin
  2517. if l>=4 then
  2518. alignment:=4
  2519. else
  2520. if l>=2 then
  2521. alignment:=2
  2522. else
  2523. alignment:=1;
  2524. end
  2525. else
  2526. alignment:=symtable.dataalignment;
  2527. end
  2528. else
  2529. alignment:=symtable.dataalignment;
  2530. end;
  2531. {$ifdef GDB}
  2532. function trecorddef.stabstring : pchar;
  2533. begin
  2534. GetMem(stabrecstring,memsizeinc);
  2535. stabrecsize:=memsizeinc;
  2536. strpcopy(stabRecString,'s'+tostr(size));
  2537. RecOffset := 0;
  2538. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  2539. strpcopy(strend(StabRecString),';');
  2540. stabstring := strnew(StabRecString);
  2541. Freemem(stabrecstring,stabrecsize);
  2542. end;
  2543. procedure trecorddef.concatstabto(asmlist : taasmoutput);
  2544. begin
  2545. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2546. (is_def_stab_written = not_written) then
  2547. inherited concatstabto(asmlist);
  2548. end;
  2549. {$endif GDB}
  2550. procedure trecorddef.write_child_rtti_data(rt:trttitype);
  2551. begin
  2552. FRTTIType:=rt;
  2553. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti);
  2554. end;
  2555. procedure trecorddef.write_rtti_data(rt:trttitype);
  2556. begin
  2557. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2558. write_rtti_name;
  2559. rttiList.concat(Tai_const.Create_32bit(size));
  2560. Count:=0;
  2561. FRTTIType:=rt;
  2562. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti);
  2563. rttiList.concat(Tai_const.Create_32bit(Count));
  2564. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
  2565. end;
  2566. function trecorddef.gettypename : string;
  2567. begin
  2568. gettypename:='<record type>'
  2569. end;
  2570. {***************************************************************************
  2571. TABSTRACTPROCDEF
  2572. ***************************************************************************}
  2573. constructor tabstractprocdef.create;
  2574. begin
  2575. inherited create;
  2576. para:=TParaLinkedList.Create;
  2577. minparacount:=0;
  2578. maxparacount:=0;
  2579. proctypeoption:=potype_none;
  2580. proccalloption:=pocall_none;
  2581. procoptions:=[];
  2582. rettype:=voidtype;
  2583. symtablelevel:=0;
  2584. fpu_used:=0;
  2585. savesize:=target_info.size_of_pointer;
  2586. end;
  2587. destructor tabstractprocdef.destroy;
  2588. begin
  2589. Para.Free;
  2590. inherited destroy;
  2591. end;
  2592. procedure tabstractprocdef.concatpara(const tt:ttype;vsp : tvarspez;defval:tsym);
  2593. var
  2594. hp : TParaItem;
  2595. begin
  2596. hp:=TParaItem.Create;
  2597. hp.paratyp:=vsp;
  2598. hp.paratype:=tt;
  2599. hp.register:=R_NO;
  2600. hp.defaultvalue:=defval;
  2601. Para.insert(hp);
  2602. if not assigned(defval) then
  2603. inc(minparacount);
  2604. inc(maxparacount);
  2605. end;
  2606. { all functions returning in FPU are
  2607. assume to use 2 FPU registers
  2608. until the function implementation
  2609. is processed PM }
  2610. procedure tabstractprocdef.test_if_fpu_result;
  2611. begin
  2612. if assigned(rettype.def) and
  2613. (rettype.def.deftype=floatdef) then
  2614. {$ifdef FAST_FPU}
  2615. fpu_used:=3;
  2616. {$else : not FAST_FPU, i.e. SAFE_FPU}
  2617. fpu_used:={2}maxfpuregs;
  2618. {$endif FAST_FPU}
  2619. end;
  2620. procedure tabstractprocdef.deref;
  2621. var
  2622. hp : TParaItem;
  2623. begin
  2624. inherited deref;
  2625. rettype.resolve;
  2626. hp:=TParaItem(Para.first);
  2627. while assigned(hp) do
  2628. begin
  2629. hp.paratype.resolve;
  2630. resolvesym(tsym(hp.defaultvalue));
  2631. hp:=TParaItem(hp.next);
  2632. end;
  2633. end;
  2634. constructor tabstractprocdef.load(ppufile:tcompilerppufile);
  2635. var
  2636. hp : TParaItem;
  2637. count,i : word;
  2638. begin
  2639. inherited loaddef(ppufile);
  2640. Para:=TParaLinkedList.Create;
  2641. minparacount:=0;
  2642. maxparacount:=0;
  2643. ppufile.gettype(rettype);
  2644. fpu_used:=ppufile.getbyte;
  2645. proctypeoption:=tproctypeoption(ppufile.getbyte);
  2646. proccalloption:=tproccalloption(ppufile.getbyte);
  2647. ppufile.getsmallset(procoptions);
  2648. count:=ppufile.getword;
  2649. savesize:=target_info.size_of_pointer;
  2650. for i:=1 to count do
  2651. begin
  2652. hp:=TParaItem.Create;
  2653. hp.paratyp:=tvarspez(ppufile.getbyte);
  2654. { hp.register:=tregister(ppufile.getbyte); }
  2655. hp.register:=R_NO;
  2656. ppufile.gettype(hp.paratype);
  2657. hp.defaultvalue:=tsym(ppufile.getderef);
  2658. if not assigned(hp.defaultvalue) then
  2659. inc(minparacount);
  2660. inc(maxparacount);
  2661. Para.concat(hp);
  2662. end;
  2663. end;
  2664. procedure tabstractprocdef.write(ppufile:tcompilerppufile);
  2665. var
  2666. hp : TParaItem;
  2667. oldintfcrc : boolean;
  2668. begin
  2669. inherited writedef(ppufile);
  2670. ppufile.puttype(rettype);
  2671. oldintfcrc:=ppufile.do_interface_crc;
  2672. ppufile.do_interface_crc:=false;
  2673. if simplify_ppu then
  2674. fpu_used:=0;
  2675. ppufile.putbyte(fpu_used);
  2676. ppufile.putbyte(ord(proctypeoption));
  2677. ppufile.putbyte(ord(proccalloption));
  2678. ppufile.putsmallset(procoptions);
  2679. ppufile.do_interface_crc:=oldintfcrc;
  2680. ppufile.putword(maxparacount);
  2681. hp:=TParaItem(Para.first);
  2682. while assigned(hp) do
  2683. begin
  2684. ppufile.putbyte(byte(hp.paratyp));
  2685. { ppufile.putbyte(byte(hp.register)); }
  2686. ppufile.puttype(hp.paratype);
  2687. ppufile.putderef(hp.defaultvalue);
  2688. hp:=TParaItem(hp.next);
  2689. end;
  2690. end;
  2691. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2692. var
  2693. pdc : TParaItem;
  2694. l : longint;
  2695. begin
  2696. l:=0;
  2697. pdc:=TParaItem(Para.first);
  2698. while assigned(pdc) do
  2699. begin
  2700. case pdc.paratyp of
  2701. vs_out,
  2702. vs_var : inc(l,target_info.size_of_pointer);
  2703. vs_value,
  2704. vs_const : if push_addr_param(pdc.paratype.def) then
  2705. inc(l,target_info.size_of_pointer)
  2706. else
  2707. inc(l,pdc.paratype.def.size);
  2708. end;
  2709. l:=align(l,alignsize);
  2710. pdc:=TParaItem(pdc.next);
  2711. end;
  2712. para_size:=l;
  2713. end;
  2714. function tabstractprocdef.demangled_paras : string;
  2715. var
  2716. hs,s : string;
  2717. hp : TParaItem;
  2718. hpc : tconstsym;
  2719. begin
  2720. hp:=TParaItem(Para.last);
  2721. if not(assigned(hp)) then
  2722. begin
  2723. demangled_paras:='';
  2724. exit;
  2725. end;
  2726. s:='(';
  2727. while assigned(hp) do
  2728. begin
  2729. if hp.paratyp=vs_var then
  2730. s:=s+'var'
  2731. else if hp.paratyp=vs_const then
  2732. s:=s+'const'
  2733. else if hp.paratyp=vs_out then
  2734. s:=s+'out';
  2735. if assigned(hp.paratype.def.typesym) then
  2736. begin
  2737. if hp.paratyp in [vs_var,vs_const,vs_out] then
  2738. s := s + ' ';
  2739. s:=s+hp.paratype.def.typesym.realname;
  2740. end;
  2741. { default value }
  2742. if assigned(hp.defaultvalue) then
  2743. begin
  2744. hpc:=tconstsym(hp.defaultvalue);
  2745. hs:='';
  2746. case hpc.consttyp of
  2747. conststring,
  2748. constresourcestring :
  2749. hs:=strpas(pchar(hpc.valueptr));
  2750. constreal :
  2751. str(pbestreal(hpc.valueptr)^,hs);
  2752. constord :
  2753. hs:=tostr(hpc.valueord);
  2754. constpointer :
  2755. hs:=tostr(hpc.valueordptr);
  2756. constbool :
  2757. begin
  2758. if hpc.valueord<>0 then
  2759. hs:='TRUE'
  2760. else
  2761. hs:='FALSE';
  2762. end;
  2763. constnil :
  2764. hs:='nil';
  2765. constchar :
  2766. hs:=chr(hpc.valueord);
  2767. constset :
  2768. hs:='<set>';
  2769. end;
  2770. if hs<>'' then
  2771. s:=s+'="'+hs+'"';
  2772. end;
  2773. hp:=TParaItem(hp.previous);
  2774. if assigned(hp) then
  2775. s:=s+',';
  2776. end;
  2777. s:=s+')';
  2778. if (po_varargs in procoptions) then
  2779. s:=s+';VarArgs';
  2780. demangled_paras:=s;
  2781. end;
  2782. {$ifdef GDB}
  2783. function tabstractprocdef.stabstring : pchar;
  2784. begin
  2785. stabstring := strpnew('abstractproc'+numberstring+';');
  2786. end;
  2787. procedure tabstractprocdef.concatstabto(asmlist : taasmoutput);
  2788. begin
  2789. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2790. and (is_def_stab_written = not_written) then
  2791. begin
  2792. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2793. inherited concatstabto(asmlist);
  2794. end;
  2795. end;
  2796. {$endif GDB}
  2797. {***************************************************************************
  2798. TPROCDEF
  2799. ***************************************************************************}
  2800. constructor tprocdef.create;
  2801. begin
  2802. inherited create;
  2803. deftype:=procdef;
  2804. has_mangledname:=false;
  2805. _mangledname:=nil;
  2806. fileinfo:=aktfilepos;
  2807. extnumber:=-1;
  2808. aliasnames:=tstringlist.create;
  2809. localst:=tlocalsymtable.create;
  2810. parast:=tparasymtable.create;
  2811. funcretsym:=nil;
  2812. localst.defowner:=self;
  2813. parast.defowner:=self;
  2814. { this is used by insert
  2815. to check same names in parast and localst }
  2816. localst.next:=parast;
  2817. defref:=nil;
  2818. crossref:=nil;
  2819. lastwritten:=nil;
  2820. refcount:=0;
  2821. if (cs_browser in aktmoduleswitches) and make_ref then
  2822. begin
  2823. defref:=tref.create(defref,@akttokenpos);
  2824. inc(refcount);
  2825. end;
  2826. lastref:=defref;
  2827. { first, we assume that all registers are used }
  2828. {$ifdef newcg}
  2829. usedregisters:=[firstreg..lastreg];
  2830. {$else newcg}
  2831. {$ifdef i386}
  2832. usedregisters:=$ff;
  2833. {$endif i386}
  2834. {$ifdef POWERPC}
  2835. { on the PPC, we use the OS specific standard calling conventions }
  2836. { so the information about the used register isn't necessary yet }
  2837. usedregisters:=0;
  2838. {$endif POWERPC}
  2839. {$endif newcg}
  2840. forwarddef:=true;
  2841. interfacedef:=false;
  2842. hasforward:=false;
  2843. _class := nil;
  2844. code:=nil;
  2845. regvarinfo := nil;
  2846. count:=false;
  2847. is_used:=false;
  2848. end;
  2849. constructor tprocdef.load(ppufile:tcompilerppufile);
  2850. begin
  2851. inherited load(ppufile);
  2852. deftype:=procdef;
  2853. {$ifdef newcg}
  2854. readnormalset(usedregisters);
  2855. {$else newcg}
  2856. {$ifdef i386}
  2857. usedregisters:=ppufile.getbyte;
  2858. {$else}
  2859. {$ifdef POWERPC}
  2860. { on the PPC, we use the OS specific standard calling conventions }
  2861. { so the information about the used register isn't necessary yet }
  2862. usedregisters:=0;
  2863. {$else POWERPC}
  2864. readnormalset(usedregisters);
  2865. {$endif POWERPC}
  2866. {$endif}
  2867. {$endif newcg}
  2868. has_mangledname:=true;
  2869. _mangledname:=stringdup(ppufile.getstring);
  2870. extnumber:=ppufile.getlongint;
  2871. _class := tobjectdef(ppufile.getderef);
  2872. procsym := tsym(ppufile.getderef);
  2873. ppufile.getposinfo(fileinfo);
  2874. { inline stuff }
  2875. if proccalloption=pocall_inline then
  2876. funcretsym:=tsym(ppufile.getderef)
  2877. else
  2878. funcretsym:=nil;
  2879. { load para and local symtables }
  2880. parast:=tparasymtable.create;
  2881. tparasymtable(parast).load(ppufile);
  2882. parast.defowner:=self;
  2883. if (proccalloption=pocall_inline) or
  2884. ((current_module.flags and uf_local_browser)<>0) then
  2885. begin
  2886. localst:=tlocalsymtable.create;
  2887. tlocalsymtable(localst).load(ppufile);
  2888. localst.defowner:=self;
  2889. end
  2890. else
  2891. localst:=nil;
  2892. { default values for no persistent data }
  2893. if (cs_link_deffile in aktglobalswitches) and
  2894. (tf_need_export in target_info.flags) and
  2895. (po_exports in procoptions) then
  2896. deffile.AddExport(mangledname);
  2897. aliasnames:=tstringlist.create;
  2898. forwarddef:=false;
  2899. interfacedef:=false;
  2900. hasforward:=false;
  2901. code := nil;
  2902. regvarinfo := nil;
  2903. lastref:=nil;
  2904. lastwritten:=nil;
  2905. defref:=nil;
  2906. refcount:=0;
  2907. count:=true;
  2908. is_used:=false;
  2909. end;
  2910. destructor tprocdef.destroy;
  2911. begin
  2912. if assigned(defref) then
  2913. begin
  2914. defref.freechain;
  2915. defref.free;
  2916. end;
  2917. aliasnames.free;
  2918. if assigned(parast) then
  2919. parast.free;
  2920. if assigned(localst) and (localst.symtabletype<>staticsymtable) then
  2921. localst.free;
  2922. if (proccalloption=pocall_inline) and assigned(code) then
  2923. tnode(code).free;
  2924. if assigned(regvarinfo) then
  2925. dispose(pregvarinfo(regvarinfo));
  2926. if (po_msgstr in procoptions) then
  2927. strdispose(messageinf.str);
  2928. if assigned(_mangledname) then
  2929. stringdispose(_mangledname);
  2930. inherited destroy;
  2931. end;
  2932. procedure tprocdef.write(ppufile:tcompilerppufile);
  2933. var
  2934. oldintfcrc : boolean;
  2935. begin
  2936. inherited write(ppufile);
  2937. oldintfcrc:=ppufile.do_interface_crc;
  2938. ppufile.do_interface_crc:=false;
  2939. { set all registers to used for simplified compilation PM }
  2940. if simplify_ppu then
  2941. begin
  2942. {$ifdef newcg}
  2943. usedregisters:=[firstreg..lastreg];
  2944. {$else newcg}
  2945. {$ifdef i386}
  2946. usedregisters:=$ff;
  2947. {$else}
  2948. {$ifdef POWERPC}
  2949. { on the PPC, we use the OS specific standard calling conventions }
  2950. { so the information about the used register isn't necessary yet }
  2951. usedregisters:=0;
  2952. {$else POWERPC}
  2953. usedregisters:=[firstreg..lastreg];
  2954. {$endif POWERPC}
  2955. {$endif i386}
  2956. {$endif newcg}
  2957. end;
  2958. {$ifdef newcg}
  2959. writenormalset(usedregisters);
  2960. {$else newcg}
  2961. {$ifdef i386}
  2962. ppufile.putbyte(usedregisters);
  2963. {$else}
  2964. {$ifdef POWERPC}
  2965. { on the PPC, we use the OS specific standard calling conventions }
  2966. { so the information about the used register isn't necessary yet }
  2967. {$else POWERPC}
  2968. writenormalset(usedregisters);
  2969. {$endif POWERPC}
  2970. {$endif i386}
  2971. {$endif newcg}
  2972. ppufile.do_interface_crc:=oldintfcrc;
  2973. ppufile.putstring(mangledname);
  2974. ppufile.putlongint(extnumber);
  2975. ppufile.putderef(_class);
  2976. ppufile.putderef(procsym);
  2977. ppufile.putposinfo(fileinfo);
  2978. { inline stuff references to localsymtable, no influence
  2979. on the crc }
  2980. oldintfcrc:=ppufile.do_crc;
  2981. ppufile.do_crc:=false;
  2982. if (proccalloption=pocall_inline) then
  2983. ppufile.putderef(funcretsym);
  2984. ppufile.do_crc:=oldintfcrc;
  2985. { write this entry }
  2986. ppufile.writeentry(ibprocdef);
  2987. { Save the para symtable, this is taken from the interface }
  2988. if not assigned(parast) then
  2989. begin
  2990. parast:=tparasymtable.create;
  2991. parast.defowner:=self;
  2992. end;
  2993. tparasymtable(parast).write(ppufile);
  2994. { save localsymtable for inline procedures or when local
  2995. browser info is requested, this has no influence on the crc }
  2996. if (proccalloption=pocall_inline) or
  2997. ((current_module.flags and uf_local_browser)<>0) then
  2998. begin
  2999. oldintfcrc:=ppufile.do_crc;
  3000. ppufile.do_crc:=false;
  3001. if not assigned(localst) then
  3002. begin
  3003. localst:=tlocalsymtable.create;
  3004. localst.defowner:=self;
  3005. end;
  3006. tlocalsymtable(localst).write(ppufile);
  3007. ppufile.do_crc:=oldintfcrc;
  3008. end;
  3009. end;
  3010. function tprocdef.fullprocname:string;
  3011. var
  3012. s : string;
  3013. begin
  3014. s:='';
  3015. if assigned(_class) then
  3016. s:=_class.objname^+'.';
  3017. s:=s+procsym.realname+demangled_paras;
  3018. fullprocname:=s;
  3019. end;
  3020. function tprocdef.fullprocnamewithret:string;
  3021. var
  3022. s : string;
  3023. begin
  3024. s:=fullprocname;
  3025. if assigned(rettype.def) and
  3026. not(is_equal(rettype.def,voidtype.def)) then
  3027. s:=s+' : '+rettype.def.gettypename;
  3028. fullprocnamewithret:=s;
  3029. end;
  3030. function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
  3031. begin
  3032. case t of
  3033. gs_local :
  3034. getsymtable:=localst;
  3035. gs_para :
  3036. getsymtable:=parast;
  3037. else
  3038. getsymtable:=nil;
  3039. end;
  3040. end;
  3041. procedure tprocdef.load_references(ppufile:tcompilerppufile;locals:boolean);
  3042. var
  3043. pos : tfileposinfo;
  3044. move_last : boolean;
  3045. begin
  3046. move_last:=lastwritten=lastref;
  3047. while (not ppufile.endofentry) do
  3048. begin
  3049. ppufile.getposinfo(pos);
  3050. inc(refcount);
  3051. lastref:=tref.create(lastref,@pos);
  3052. lastref.is_written:=true;
  3053. if refcount=1 then
  3054. defref:=lastref;
  3055. end;
  3056. if move_last then
  3057. lastwritten:=lastref;
  3058. if ((current_module.flags and uf_local_browser)<>0) and
  3059. locals then
  3060. begin
  3061. tparasymtable(parast).load_references(ppufile,locals);
  3062. tlocalsymtable(localst).load_references(ppufile,locals);
  3063. end;
  3064. end;
  3065. Const
  3066. local_symtable_index : longint = $8001;
  3067. function tprocdef.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  3068. var
  3069. ref : tref;
  3070. pdo : tobjectdef;
  3071. move_last : boolean;
  3072. begin
  3073. move_last:=lastwritten=lastref;
  3074. if move_last and
  3075. (((current_module.flags and uf_local_browser)=0) or
  3076. not locals) then
  3077. exit;
  3078. { write address of this symbol }
  3079. ppufile.putderef(self);
  3080. { write refs }
  3081. if assigned(lastwritten) then
  3082. ref:=lastwritten
  3083. else
  3084. ref:=defref;
  3085. while assigned(ref) do
  3086. begin
  3087. if ref.moduleindex=current_module.unit_index then
  3088. begin
  3089. ppufile.putposinfo(ref.posinfo);
  3090. ref.is_written:=true;
  3091. if move_last then
  3092. lastwritten:=ref;
  3093. end
  3094. else if not ref.is_written then
  3095. move_last:=false
  3096. else if move_last then
  3097. lastwritten:=ref;
  3098. ref:=ref.nextref;
  3099. end;
  3100. ppufile.writeentry(ibdefref);
  3101. write_references:=true;
  3102. if ((current_module.flags and uf_local_browser)<>0) and
  3103. locals then
  3104. begin
  3105. pdo:=_class;
  3106. if (owner.symtabletype<>localsymtable) then
  3107. while assigned(pdo) do
  3108. begin
  3109. if pdo.symtable<>aktrecordsymtable then
  3110. begin
  3111. pdo.symtable.unitid:=local_symtable_index;
  3112. inc(local_symtable_index);
  3113. end;
  3114. pdo:=pdo.childof;
  3115. end;
  3116. parast.unitid:=local_symtable_index;
  3117. inc(local_symtable_index);
  3118. localst.unitid:=local_symtable_index;
  3119. inc(local_symtable_index);
  3120. tstoredsymtable(parast).write_references(ppufile,locals);
  3121. tstoredsymtable(localst).write_references(ppufile,locals);
  3122. { decrement for }
  3123. local_symtable_index:=local_symtable_index-2;
  3124. pdo:=_class;
  3125. if (owner.symtabletype<>localsymtable) then
  3126. while assigned(pdo) do
  3127. begin
  3128. if pdo.symtable<>aktrecordsymtable then
  3129. dec(local_symtable_index);
  3130. pdo:=pdo.childof;
  3131. end;
  3132. end;
  3133. end;
  3134. function tprocdef.haspara:boolean;
  3135. begin
  3136. haspara:=assigned(parast.symindex.first);
  3137. end;
  3138. {$ifdef GDB}
  3139. { procedure addparaname(p : tsym);
  3140. var vs : char;
  3141. begin
  3142. if tvarsym(p).varspez = vs_value then vs := '1'
  3143. else vs := '0';
  3144. strpcopy(strend(StabRecString),p^.name+':'+tstoreddef(tvarsym(p).vartype.def).numberstring+','+vs+';');
  3145. end; }
  3146. function tprocdef.stabstring : pchar;
  3147. var
  3148. i : longint;
  3149. stabrecstring : pchar;
  3150. begin
  3151. getmem(StabRecString,1024);
  3152. strpcopy(StabRecString,'f'+tstoreddef(rettype.def).numberstring);
  3153. i:=maxparacount;
  3154. if i>0 then
  3155. begin
  3156. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3157. (* confuse gdb !! PM
  3158. if assigned(parast) then
  3159. parast.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3160. else
  3161. begin
  3162. param := para1;
  3163. i := 0;
  3164. while assigned(param) do
  3165. begin
  3166. inc(i);
  3167. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3168. {Here we have lost the parameter names !!}
  3169. {using lower case parameters }
  3170. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3171. +':'+param^.paratype.def.numberstring+','+vartyp+';');
  3172. param := param^.next;
  3173. end;
  3174. end; *)
  3175. {strpcopy(strend(StabRecString),';');}
  3176. end;
  3177. stabstring := strnew(stabrecstring);
  3178. freemem(stabrecstring,1024);
  3179. end;
  3180. procedure tprocdef.concatstabto(asmlist : taasmoutput);
  3181. begin
  3182. end;
  3183. {$endif GDB}
  3184. procedure tprocdef.deref;
  3185. var
  3186. oldlocalsymtable : tsymtable;
  3187. begin
  3188. inherited deref;
  3189. resolvedef(tdef(_class));
  3190. { parast }
  3191. oldlocalsymtable:=aktlocalsymtable;
  3192. aktlocalsymtable:=parast;
  3193. tparasymtable(parast).deref;
  3194. aktlocalsymtable:=oldlocalsymtable;
  3195. { procsym that originaly defined this definition, should be in the
  3196. same symtable }
  3197. resolvesym(procsym);
  3198. end;
  3199. procedure tprocdef.derefimpl;
  3200. var
  3201. oldlocalsymtable : tsymtable;
  3202. begin
  3203. { locals }
  3204. if assigned(localst) then
  3205. begin
  3206. { localst }
  3207. oldlocalsymtable:=aktlocalsymtable;
  3208. aktlocalsymtable:=localst;
  3209. { we can deref both interface and implementation parts }
  3210. tlocalsymtable(localst).deref;
  3211. tlocalsymtable(localst).derefimpl;
  3212. aktlocalsymtable:=oldlocalsymtable;
  3213. { funcretsym, this is always located in the localst }
  3214. resolvesym(funcretsym);
  3215. end
  3216. else
  3217. begin
  3218. { safety }
  3219. funcretsym:=nil;
  3220. end;
  3221. end;
  3222. function tprocdef.mangledname : string;
  3223. begin
  3224. if assigned(_mangledname) then
  3225. mangledname:=_mangledname^
  3226. else
  3227. mangledname:='';
  3228. if count then
  3229. is_used:=true;
  3230. end;
  3231. function tprocdef.cplusplusmangledname : string;
  3232. function getcppparaname(p : tdef) : string;
  3233. const
  3234. ordtype2str : array[tbasetype] of string[2] = (
  3235. '','','c',
  3236. 'Uc','Us','Ui',
  3237. 'Sc','s','i',
  3238. 'b','b','b',
  3239. 'Us','x','w');
  3240. var
  3241. s : string;
  3242. begin
  3243. case p.deftype of
  3244. orddef:
  3245. s:=ordtype2str[torddef(p).typ];
  3246. pointerdef:
  3247. s:='P'+getcppparaname(tpointerdef(p).pointertype.def);
  3248. else
  3249. internalerror(2103001);
  3250. end;
  3251. getcppparaname:=s;
  3252. end;
  3253. var
  3254. s,s2 : string;
  3255. param : TParaItem;
  3256. begin
  3257. s := procsym.realname;
  3258. if procsym.owner.symtabletype=objectsymtable then
  3259. begin
  3260. s2:=upper(tobjectdef(procsym.owner.defowner).typesym.realname);
  3261. case proctypeoption of
  3262. potype_destructor:
  3263. s:='_$_'+tostr(length(s2))+s2;
  3264. potype_constructor:
  3265. s:='___'+tostr(length(s2))+s2;
  3266. else
  3267. s:='_'+s+'__'+tostr(length(s2))+s2;
  3268. end;
  3269. end
  3270. else s:=s+'__';
  3271. s:=s+'F';
  3272. { concat modifiers }
  3273. { !!!!! }
  3274. { now we handle the parameters }
  3275. param := TParaItem(Para.first);
  3276. if assigned(param) then
  3277. while assigned(param) do
  3278. begin
  3279. s2:=getcppparaname(param.paratype.def);
  3280. if param.paratyp in [vs_var,vs_out] then
  3281. s2:='R'+s2;
  3282. s:=s+s2;
  3283. param:=TParaItem(param.next);
  3284. end
  3285. else
  3286. s:=s+'v';
  3287. cplusplusmangledname:=s;
  3288. end;
  3289. procedure tprocdef.setmangledname(const s : string);
  3290. begin
  3291. if assigned(_mangledname) then
  3292. begin
  3293. {$ifdef MEMDEBUG}
  3294. dec(manglenamesize,length(_mangledname^));
  3295. {$endif}
  3296. stringdispose(_mangledname);
  3297. end;
  3298. _mangledname:=stringdup(s);
  3299. {$ifdef MEMDEBUG}
  3300. inc(manglenamesize,length(s));
  3301. {$endif}
  3302. {$ifdef EXTDEBUG}
  3303. if assigned(parast) then
  3304. begin
  3305. stringdispose(parast.name);
  3306. parast.name:=stringdup('args of '+s);
  3307. end;
  3308. if assigned(localst) then
  3309. begin
  3310. stringdispose(localst.name);
  3311. localst.name:=stringdup('locals of '+s);
  3312. end;
  3313. {$endif}
  3314. end;
  3315. {***************************************************************************
  3316. TPROCVARDEF
  3317. ***************************************************************************}
  3318. constructor tprocvardef.create;
  3319. begin
  3320. inherited create;
  3321. deftype:=procvardef;
  3322. end;
  3323. constructor tprocvardef.load(ppufile:tcompilerppufile);
  3324. begin
  3325. inherited load(ppufile);
  3326. deftype:=procvardef;
  3327. end;
  3328. procedure tprocvardef.write(ppufile:tcompilerppufile);
  3329. begin
  3330. { here we cannot get a real good value so just give something }
  3331. { plausible (PM) }
  3332. { a more secure way would be
  3333. to allways store in a temp }
  3334. if is_fpu(rettype.def) then
  3335. {$ifdef FAST_FPU}
  3336. fpu_used:=3
  3337. {$else : not FAST_FPU, i.e. SAFE_FPU}
  3338. fpu_used:={2}maxfpuregs
  3339. {$endif FAST_FPU}
  3340. else
  3341. fpu_used:=0;
  3342. inherited write(ppufile);
  3343. ppufile.writeentry(ibprocvardef);
  3344. end;
  3345. function tprocvardef.size : longint;
  3346. begin
  3347. if (po_methodpointer in procoptions) then
  3348. size:=2*target_info.size_of_pointer
  3349. else
  3350. size:=target_info.size_of_pointer;
  3351. end;
  3352. {$ifdef GDB}
  3353. function tprocvardef.stabstring : pchar;
  3354. var
  3355. nss : pchar;
  3356. { i : longint; }
  3357. begin
  3358. { i := maxparacount; }
  3359. getmem(nss,1024);
  3360. { it is not a function but a function pointer !! (PM) }
  3361. strpcopy(nss,'*f'+tstoreddef(rettype.def).numberstring{+','+tostr(i)}+';');
  3362. { this confuses gdb !!
  3363. we should use 'F' instead of 'f' but
  3364. as we use c++ language mode
  3365. it does not like that either
  3366. Please do not remove this part
  3367. might be used once
  3368. gdb for pascal is ready PM }
  3369. (*
  3370. param := para1;
  3371. i := 0;
  3372. while assigned(param) do
  3373. begin
  3374. inc(i);
  3375. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3376. {Here we have lost the parameter names !!}
  3377. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def.numberstring+','+vartyp+';');
  3378. strcat(nss,pst);
  3379. strdispose(pst);
  3380. param := param^.next;
  3381. end; *)
  3382. {strpcopy(strend(nss),';');}
  3383. stabstring := strnew(nss);
  3384. freemem(nss,1024);
  3385. end;
  3386. procedure tprocvardef.concatstabto(asmlist : taasmoutput);
  3387. begin
  3388. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3389. and (is_def_stab_written = not_written) then
  3390. inherited concatstabto(asmlist);
  3391. is_def_stab_written:=written;
  3392. end;
  3393. {$endif GDB}
  3394. procedure tprocvardef.write_rtti_data(rt:trttitype);
  3395. var
  3396. pdc : TParaItem;
  3397. methodkind, paraspec : byte;
  3398. begin
  3399. if po_methodpointer in procoptions then
  3400. begin
  3401. { write method id and name }
  3402. rttiList.concat(Tai_const.Create_8bit(tkmethod));
  3403. write_rtti_name;
  3404. { write kind of method (can only be function or procedure)}
  3405. if rettype.def = voidtype.def then
  3406. methodkind := mkProcedure
  3407. else
  3408. methodkind := mkFunction;
  3409. rttiList.concat(Tai_const.Create_8bit(methodkind));
  3410. { get # of parameters }
  3411. rttiList.concat(Tai_const.Create_8bit(maxparacount));
  3412. { write parameter info. The parameters must be written in reverse order
  3413. if this method uses right to left parameter pushing! }
  3414. if (po_leftright in procoptions) then
  3415. pdc:=TParaItem(Para.last)
  3416. else
  3417. pdc:=TParaItem(Para.first);
  3418. while assigned(pdc) do
  3419. begin
  3420. case pdc.paratyp of
  3421. vs_value: paraspec := 0;
  3422. vs_const: paraspec := pfConst;
  3423. vs_var : paraspec := pfVar;
  3424. vs_out : paraspec := pfOut;
  3425. end;
  3426. { write flags for current parameter }
  3427. rttiList.concat(Tai_const.Create_8bit(paraspec));
  3428. { write name of current parameter ### how can I get this??? (sg)}
  3429. rttiList.concat(Tai_const.Create_8bit(0));
  3430. { write name of type of current parameter }
  3431. tstoreddef(pdc.paratype.def).write_rtti_name;
  3432. if (po_leftright in procoptions) then
  3433. pdc:=TParaItem(pdc.previous)
  3434. else
  3435. pdc:=TParaItem(pdc.next);
  3436. end;
  3437. { write name of result type }
  3438. tstoreddef(rettype.def).write_rtti_name;
  3439. end;
  3440. end;
  3441. function tprocvardef.is_publishable : boolean;
  3442. begin
  3443. is_publishable:=(po_methodpointer in procoptions);
  3444. end;
  3445. function tprocvardef.gettypename : string;
  3446. var
  3447. s: string;
  3448. begin
  3449. if assigned(rettype.def) and
  3450. (rettype.def<>voidtype.def) then
  3451. s:='<procedure variable type of function'+demangled_paras+
  3452. ':'+rettype.def.gettypename
  3453. else
  3454. s:='<procedure variable type of procedure'+demangled_paras;
  3455. if po_methodpointer in procoptions then
  3456. s := s+' of object';
  3457. gettypename := s+';'+ProcCallOptionStr[proccalloption]+'>';
  3458. end;
  3459. {***************************************************************************
  3460. TOBJECTDEF
  3461. ***************************************************************************}
  3462. {$ifdef GDB}
  3463. const
  3464. vtabletype : word = 0;
  3465. vtableassigned : boolean = false;
  3466. {$endif GDB}
  3467. constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  3468. begin
  3469. inherited create;
  3470. objecttype:=ot;
  3471. deftype:=objectdef;
  3472. objectoptions:=[];
  3473. childof:=nil;
  3474. symtable:=tobjectsymtable.create(n);
  3475. { create space for vmt !! }
  3476. vmt_offset:=0;
  3477. symtable.datasize:=0;
  3478. symtable.defowner:=self;
  3479. { recordalign -1 means C record packing, that starts
  3480. with an alignment of 1 }
  3481. if aktalignment.recordalignmax=-1 then
  3482. symtable.dataalignment:=1
  3483. else
  3484. symtable.dataalignment:=aktalignment.recordalignmax;
  3485. lastvtableindex:=0;
  3486. set_parent(c);
  3487. objname:=stringdup(n);
  3488. { set up guid }
  3489. isiidguidvalid:=true; { default null guid }
  3490. fillchar(iidguid,sizeof(iidguid),0); { default null guid }
  3491. iidstr:=stringdup(''); { default is empty string }
  3492. { setup implemented interfaces }
  3493. if objecttype in [odt_class,odt_interfacecorba] then
  3494. implementedinterfaces:=timplementedinterfaces.create
  3495. else
  3496. implementedinterfaces:=nil;
  3497. {$ifdef GDB}
  3498. writing_class_record_stab:=false;
  3499. {$endif GDB}
  3500. end;
  3501. constructor tobjectdef.load(ppufile:tcompilerppufile);
  3502. var
  3503. oldread_member : boolean;
  3504. i,implintfcount: longint;
  3505. begin
  3506. inherited loaddef(ppufile);
  3507. deftype:=objectdef;
  3508. objecttype:=tobjectdeftype(ppufile.getbyte);
  3509. savesize:=ppufile.getlongint;
  3510. vmt_offset:=ppufile.getlongint;
  3511. objname:=stringdup(ppufile.getstring);
  3512. childof:=tobjectdef(ppufile.getderef);
  3513. ppufile.getsmallset(objectoptions);
  3514. { load guid }
  3515. iidstr:=nil;
  3516. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3517. begin
  3518. isiidguidvalid:=boolean(ppufile.getbyte);
  3519. ppufile.putguid(iidguid);
  3520. iidstr:=stringdup(ppufile.getstring);
  3521. lastvtableindex:=ppufile.getlongint;
  3522. end;
  3523. { load implemented interfaces }
  3524. if objecttype in [odt_class,odt_interfacecorba] then
  3525. begin
  3526. implementedinterfaces:=timplementedinterfaces.create;
  3527. implintfcount:=ppufile.getlongint;
  3528. for i:=1 to implintfcount do
  3529. begin
  3530. implementedinterfaces.addintfref(tdef(ppufile.getderef));
  3531. implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
  3532. end;
  3533. end
  3534. else
  3535. implementedinterfaces:=nil;
  3536. oldread_member:=read_member;
  3537. read_member:=true;
  3538. symtable:=tobjectsymtable.create(objname^);
  3539. tobjectsymtable(symtable).load(ppufile);
  3540. read_member:=oldread_member;
  3541. symtable.defowner:=self;
  3542. { handles the predefined class tobject }
  3543. { the last TOBJECT which is loaded gets }
  3544. { it ! }
  3545. if (childof=nil) and
  3546. (objecttype=odt_class) and
  3547. (upper(objname^)='TOBJECT') then
  3548. class_tobject:=self;
  3549. if (childof=nil) and
  3550. (objecttype=odt_interfacecom) and
  3551. (upper(objname^)='IUNKNOWN') then
  3552. interface_iunknown:=self;
  3553. {$ifdef GDB}
  3554. writing_class_record_stab:=false;
  3555. {$endif GDB}
  3556. end;
  3557. destructor tobjectdef.destroy;
  3558. begin
  3559. if assigned(symtable) then
  3560. symtable.free;
  3561. if (oo_is_forward in objectoptions) then
  3562. Message1(sym_e_class_forward_not_resolved,objname^);
  3563. stringdispose(objname);
  3564. stringdispose(iidstr);
  3565. if assigned(implementedinterfaces) then
  3566. implementedinterfaces.free;
  3567. inherited destroy;
  3568. end;
  3569. procedure tobjectdef.write(ppufile:tcompilerppufile);
  3570. var
  3571. oldread_member : boolean;
  3572. implintfcount : longint;
  3573. i : longint;
  3574. begin
  3575. inherited writedef(ppufile);
  3576. ppufile.putbyte(byte(objecttype));
  3577. ppufile.putlongint(size);
  3578. ppufile.putlongint(vmt_offset);
  3579. ppufile.putstring(objname^);
  3580. ppufile.putderef(childof);
  3581. ppufile.putsmallset(objectoptions);
  3582. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3583. begin
  3584. ppufile.putbyte(byte(isiidguidvalid));
  3585. ppufile.putguid(iidguid);
  3586. ppufile.putstring(iidstr^);
  3587. ppufile.putlongint(lastvtableindex);
  3588. end;
  3589. if objecttype in [odt_class,odt_interfacecorba] then
  3590. begin
  3591. implintfcount:=implementedinterfaces.count;
  3592. ppufile.putlongint(implintfcount);
  3593. for i:=1 to implintfcount do
  3594. begin
  3595. ppufile.putderef(implementedinterfaces.interfaces(i));
  3596. ppufile.putlongint(implementedinterfaces.ioffsets(i)^);
  3597. end;
  3598. end;
  3599. ppufile.writeentry(ibobjectdef);
  3600. oldread_member:=read_member;
  3601. read_member:=true;
  3602. tobjectsymtable(symtable).write(ppufile);
  3603. read_member:=oldread_member;
  3604. end;
  3605. procedure tobjectdef.deref;
  3606. var
  3607. oldrecsyms : tsymtable;
  3608. begin
  3609. inherited deref;
  3610. resolvedef(tdef(childof));
  3611. oldrecsyms:=aktrecordsymtable;
  3612. aktrecordsymtable:=symtable;
  3613. tstoredsymtable(symtable).deref;
  3614. aktrecordsymtable:=oldrecsyms;
  3615. if objecttype in [odt_class,odt_interfacecorba] then
  3616. implementedinterfaces.deref;
  3617. end;
  3618. procedure tobjectdef.set_parent( c : tobjectdef);
  3619. begin
  3620. { nothing to do if the parent was not forward !}
  3621. if assigned(childof) then
  3622. exit;
  3623. childof:=c;
  3624. { some options are inherited !! }
  3625. if assigned(c) then
  3626. begin
  3627. { only important for classes }
  3628. lastvtableindex:=c.lastvtableindex;
  3629. objectoptions:=objectoptions+(c.objectoptions*
  3630. [oo_has_virtual,oo_has_private,oo_has_protected,
  3631. oo_has_constructor,oo_has_destructor]);
  3632. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3633. begin
  3634. { add the data of the anchestor class }
  3635. inc(symtable.datasize,c.symtable.datasize);
  3636. if (oo_has_vmt in objectoptions) and
  3637. (oo_has_vmt in c.objectoptions) then
  3638. dec(symtable.datasize,target_info.size_of_pointer);
  3639. { if parent has a vmt field then
  3640. the offset is the same for the child PM }
  3641. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  3642. begin
  3643. vmt_offset:=c.vmt_offset;
  3644. include(objectoptions,oo_has_vmt);
  3645. end;
  3646. end;
  3647. end;
  3648. savesize := symtable.datasize;
  3649. end;
  3650. procedure tobjectdef.insertvmt;
  3651. begin
  3652. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3653. exit;
  3654. if (oo_has_vmt in objectoptions) then
  3655. internalerror(12345)
  3656. else
  3657. begin
  3658. symtable.datasize:=align(symtable.datasize,symtable.dataalignment);
  3659. vmt_offset:=symtable.datasize;
  3660. inc(symtable.datasize,target_info.size_of_pointer);
  3661. include(objectoptions,oo_has_vmt);
  3662. end;
  3663. end;
  3664. procedure tobjectdef.check_forwards;
  3665. begin
  3666. if not(objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3667. tstoredsymtable(symtable).check_forwards;
  3668. if (oo_is_forward in objectoptions) then
  3669. begin
  3670. { ok, in future, the forward can be resolved }
  3671. Message1(sym_e_class_forward_not_resolved,objname^);
  3672. exclude(objectoptions,oo_is_forward);
  3673. end;
  3674. end;
  3675. { true, if self inherits from d (or if they are equal) }
  3676. function tobjectdef.is_related(d : tobjectdef) : boolean;
  3677. var
  3678. hp : tobjectdef;
  3679. begin
  3680. hp:=self;
  3681. while assigned(hp) do
  3682. begin
  3683. if hp=d then
  3684. begin
  3685. is_related:=true;
  3686. exit;
  3687. end;
  3688. hp:=hp.childof;
  3689. end;
  3690. is_related:=false;
  3691. end;
  3692. procedure tobjectdef._searchdestructor(sym : tnamedindexitem);
  3693. var
  3694. p : pprocdeflist;
  3695. begin
  3696. { if we found already a destructor, then we exit }
  3697. if assigned(sd) then
  3698. exit;
  3699. if tsym(sym).typ=procsym then
  3700. begin
  3701. p:=tprocsym(sym).defs;
  3702. while assigned(p) do
  3703. begin
  3704. if p^.def.proctypeoption=potype_destructor then
  3705. begin
  3706. sd:=p^.def;
  3707. exit;
  3708. end;
  3709. p:=p^.next;
  3710. end;
  3711. end;
  3712. end;
  3713. function tobjectdef.searchdestructor : tprocdef;
  3714. var
  3715. o : tobjectdef;
  3716. begin
  3717. searchdestructor:=nil;
  3718. o:=self;
  3719. sd:=nil;
  3720. while assigned(o) do
  3721. begin
  3722. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
  3723. if assigned(sd) then
  3724. begin
  3725. searchdestructor:=sd;
  3726. exit;
  3727. end;
  3728. o:=o.childof;
  3729. end;
  3730. end;
  3731. function tobjectdef.size : longint;
  3732. begin
  3733. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3734. size:=target_info.size_of_pointer
  3735. else
  3736. size:=symtable.datasize;
  3737. end;
  3738. function tobjectdef.alignment:longint;
  3739. begin
  3740. alignment:=symtable.dataalignment;
  3741. end;
  3742. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3743. begin
  3744. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3745. case objecttype of
  3746. odt_class:
  3747. vmtmethodoffset:=(index+12)*target_info.size_of_pointer;
  3748. odt_interfacecom,odt_interfacecorba:
  3749. vmtmethodoffset:=index*target_info.size_of_pointer;
  3750. else
  3751. {$ifdef WITHDMT}
  3752. vmtmethodoffset:=(index+4)*target_info.size_of_pointer;
  3753. {$else WITHDMT}
  3754. vmtmethodoffset:=(index+3)*target_info.size_of_pointer;
  3755. {$endif WITHDMT}
  3756. end;
  3757. end;
  3758. function tobjectdef.vmt_mangledname : string;
  3759. {DM: I get a nil pointer on the owner name. I don't know if this
  3760. may happen, and I have therefore fixed the problem by doing nil pointer
  3761. checks.}
  3762. var
  3763. s1,s2:string;
  3764. begin
  3765. if not(oo_has_vmt in objectoptions) then
  3766. Message1(parser_object_has_no_vmt,objname^);
  3767. if owner.name=nil then
  3768. s1:=''
  3769. else
  3770. s1:=upper(owner.name^);
  3771. if objname=nil then
  3772. s2:=''
  3773. else
  3774. s2:=Upper(objname^);
  3775. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3776. end;
  3777. function tobjectdef.rtti_name : string;
  3778. var
  3779. s1,s2:string;
  3780. begin
  3781. if owner.name=nil then
  3782. s1:=''
  3783. else
  3784. s1:=upper(owner.name^);
  3785. if objname=nil then
  3786. s2:=''
  3787. else
  3788. s2:=Upper(objname^);
  3789. rtti_name:='RTTI_'+s1+'$_'+s2;
  3790. end;
  3791. {$ifdef GDB}
  3792. procedure tobjectdef.addprocname(p :tnamedindexitem);
  3793. var virtualind,argnames : string;
  3794. news, newrec : pchar;
  3795. pd,ipd : tprocdef;
  3796. lindex : longint;
  3797. para : TParaItem;
  3798. arglength : byte;
  3799. sp : char;
  3800. pdl : pprocdeflist;
  3801. begin
  3802. If tsym(p).typ = procsym then
  3803. begin
  3804. pd := tprocsym(p).defs^.def;
  3805. { this will be used for full implementation of object stabs
  3806. not yet done }
  3807. pdl:=tprocsym(p).defs;
  3808. while assigned(pdl) do
  3809. begin
  3810. ipd:=pdl^.def;
  3811. pdl:=pdl^.next;
  3812. end;
  3813. if (po_virtualmethod in pd.procoptions) then
  3814. begin
  3815. lindex := pd.extnumber;
  3816. {doesnt seem to be necessary
  3817. lindex := lindex or $80000000;}
  3818. virtualind := '*'+tostr(lindex)+';'+ipd._class.classnumberstring+';'
  3819. end
  3820. else
  3821. virtualind := '.';
  3822. { used by gdbpas to recognize constructor and destructors }
  3823. if (pd.proctypeoption=potype_constructor) then
  3824. argnames:='__ct__'
  3825. else if (pd.proctypeoption=potype_destructor) then
  3826. argnames:='__dt__'
  3827. else
  3828. argnames := '';
  3829. { arguments are not listed here }
  3830. {we don't need another definition}
  3831. para := TParaItem(pd.Para.first);
  3832. while assigned(para) do
  3833. begin
  3834. if Para.paratype.def.deftype = formaldef then
  3835. begin
  3836. if Para.paratyp=vs_var then
  3837. argnames := argnames+'3var'
  3838. else if Para.paratyp=vs_const then
  3839. argnames:=argnames+'5const'
  3840. else if Para.paratyp=vs_out then
  3841. argnames:=argnames+'3out';
  3842. end
  3843. else
  3844. begin
  3845. { if the arg definition is like (v: ^byte;..
  3846. there is no sym attached to data !!! }
  3847. if assigned(Para.paratype.def.typesym) then
  3848. begin
  3849. arglength := length(Para.paratype.def.typesym.name);
  3850. argnames := argnames + tostr(arglength)+Para.paratype.def.typesym.name;
  3851. end
  3852. else
  3853. begin
  3854. argnames:=argnames+'11unnamedtype';
  3855. end;
  3856. end;
  3857. para := TParaItem(Para.next);
  3858. end;
  3859. ipd.is_def_stab_written := written;
  3860. { here 2A must be changed for private and protected }
  3861. { 0 is private 1 protected and 2 public }
  3862. if (sp_private in tsym(p).symoptions) then sp:='0'
  3863. else if (sp_protected in tsym(p).symoptions) then sp:='1'
  3864. else sp:='2';
  3865. newrec := strpnew(p.name+'::'+ipd.numberstring
  3866. +'=##'+tstoreddef(pd.rettype.def).numberstring+';:'+argnames+';'+sp+'A'
  3867. +virtualind+';');
  3868. { get spare place for a string at the end }
  3869. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3870. begin
  3871. getmem(news,stabrecsize+memsizeinc);
  3872. strcopy(news,stabrecstring);
  3873. freemem(stabrecstring,stabrecsize);
  3874. stabrecsize:=stabrecsize+memsizeinc;
  3875. stabrecstring:=news;
  3876. end;
  3877. strcat(StabRecstring,newrec);
  3878. {freemem(newrec,memsizeinc); }
  3879. strdispose(newrec);
  3880. {This should be used for case !!
  3881. RecOffset := RecOffset + pd.size;}
  3882. end;
  3883. end;
  3884. function tobjectdef.stabstring : pchar;
  3885. var anc : tobjectdef;
  3886. oldrec : pchar;
  3887. oldrecsize,oldrecoffset : longint;
  3888. str_end : string;
  3889. begin
  3890. if not (objecttype=odt_class) or writing_class_record_stab then
  3891. begin
  3892. oldrec := stabrecstring;
  3893. oldrecsize:=stabrecsize;
  3894. stabrecsize:=memsizeinc;
  3895. GetMem(stabrecstring,stabrecsize);
  3896. strpcopy(stabRecString,'s'+tostr(symtable.datasize));
  3897. if assigned(childof) then
  3898. begin
  3899. {only one ancestor not virtual, public, at base offset 0 }
  3900. { !1 , 0 2 0 , }
  3901. strpcopy(strend(stabrecstring),'!1,020,'+childof.classnumberstring+';');
  3902. end;
  3903. {virtual table to implement yet}
  3904. OldRecOffset:=RecOffset;
  3905. RecOffset := 0;
  3906. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  3907. RecOffset:=OldRecOffset;
  3908. if (oo_has_vmt in objectoptions) then
  3909. if not assigned(childof) or not(oo_has_vmt in childof.objectoptions) then
  3910. begin
  3911. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  3912. +','+tostr(vmt_offset*8)+';');
  3913. end;
  3914. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
  3915. if (oo_has_vmt in objectoptions) then
  3916. begin
  3917. anc := self;
  3918. while assigned(anc.childof) and (oo_has_vmt in anc.childof.objectoptions) do
  3919. anc := anc.childof;
  3920. { just in case anc = self }
  3921. str_end:=';~%'+anc.classnumberstring+';';
  3922. end
  3923. else
  3924. str_end:=';';
  3925. strpcopy(strend(stabrecstring),str_end);
  3926. stabstring := strnew(StabRecString);
  3927. freemem(stabrecstring,stabrecsize);
  3928. stabrecstring := oldrec;
  3929. stabrecsize:=oldrecsize;
  3930. end
  3931. else
  3932. begin
  3933. stabstring:=strpnew('*'+classnumberstring);
  3934. end;
  3935. end;
  3936. procedure tobjectdef.set_globalnb;
  3937. begin
  3938. globalnb:=PglobalTypeCount^;
  3939. inc(PglobalTypeCount^);
  3940. { classes need two type numbers, the globalnb is set to the ptr }
  3941. if objecttype=odt_class then
  3942. begin
  3943. globalnb:=PGlobalTypeCount^;
  3944. inc(PglobalTypeCount^);
  3945. end;
  3946. end;
  3947. function tobjectdef.classnumberstring : string;
  3948. begin
  3949. { write stabs again if needed }
  3950. numberstring;
  3951. if objecttype=odt_class then
  3952. begin
  3953. dec(globalnb);
  3954. classnumberstring:=numberstring;
  3955. inc(globalnb);
  3956. end
  3957. else
  3958. classnumberstring:=numberstring;
  3959. end;
  3960. function tobjectdef.allstabstring : pchar;
  3961. var stabchar : string[2];
  3962. ss,st : pchar;
  3963. sname : string;
  3964. sym_line_no : longint;
  3965. begin
  3966. ss := stabstring;
  3967. getmem(st,strlen(ss)+512);
  3968. stabchar := 't';
  3969. if deftype in tagtypes then
  3970. stabchar := 'Tt';
  3971. if assigned(typesym) then
  3972. begin
  3973. sname := typesym.name;
  3974. sym_line_no:=typesym.fileinfo.line;
  3975. end
  3976. else
  3977. begin
  3978. sname := ' ';
  3979. sym_line_no:=0;
  3980. end;
  3981. if writing_class_record_stab then
  3982. strpcopy(st,'"'+sname+':'+stabchar+classnumberstring+'=')
  3983. else
  3984. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  3985. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  3986. allstabstring := strnew(st);
  3987. freemem(st,strlen(ss)+512);
  3988. strdispose(ss);
  3989. end;
  3990. procedure tobjectdef.concatstabto(asmlist : taasmoutput);
  3991. var st : pstring;
  3992. begin
  3993. if objecttype<>odt_class then
  3994. begin
  3995. inherited concatstabto(asmlist);
  3996. exit;
  3997. end;
  3998. if ((typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  3999. (is_def_stab_written = not_written) then
  4000. begin
  4001. if globalnb=0 then
  4002. set_globalnb;
  4003. { Write the record class itself }
  4004. writing_class_record_stab:=true;
  4005. inherited concatstabto(asmlist);
  4006. writing_class_record_stab:=false;
  4007. { Write the invisible pointer class }
  4008. is_def_stab_written:=not_written;
  4009. if assigned(typesym) then
  4010. begin
  4011. st:=typesym.FName;
  4012. typesym.FName:=stringdup(' ');
  4013. end;
  4014. inherited concatstabto(asmlist);
  4015. if assigned(typesym) then
  4016. begin
  4017. stringdispose(typesym.FName);
  4018. typesym.FName:=st;
  4019. end;
  4020. end;
  4021. end;
  4022. {$endif GDB}
  4023. function tobjectdef.needs_inittable : boolean;
  4024. begin
  4025. case objecttype of
  4026. odt_class :
  4027. needs_inittable:=false;
  4028. odt_interfacecom:
  4029. needs_inittable:=true;
  4030. odt_interfacecorba:
  4031. needs_inittable:=is_related(interface_iunknown);
  4032. odt_object:
  4033. needs_inittable:=tobjectsymtable(symtable).needs_init_final;
  4034. else
  4035. internalerror(200108267);
  4036. end;
  4037. end;
  4038. procedure tobjectdef.count_published_properties(sym:tnamedindexitem);
  4039. begin
  4040. if needs_prop_entry(tsym(sym)) and
  4041. (tsym(sym).typ<>varsym) then
  4042. inc(count);
  4043. end;
  4044. procedure tobjectdef.write_property_info(sym : tnamedindexitem);
  4045. var
  4046. proctypesinfo : byte;
  4047. procedure writeproc(proc : tsymlist; shiftvalue : byte);
  4048. var
  4049. typvalue : byte;
  4050. hp : psymlistitem;
  4051. address : longint;
  4052. begin
  4053. if not(assigned(proc) and assigned(proc.firstsym)) then
  4054. begin
  4055. rttiList.concat(Tai_const.Create_32bit(1));
  4056. typvalue:=3;
  4057. end
  4058. else if proc.firstsym^.sym.typ=varsym then
  4059. begin
  4060. address:=0;
  4061. hp:=proc.firstsym;
  4062. while assigned(hp) do
  4063. begin
  4064. inc(address,tvarsym(hp^.sym).address);
  4065. hp:=hp^.next;
  4066. end;
  4067. rttiList.concat(Tai_const.Create_32bit(address));
  4068. typvalue:=0;
  4069. end
  4070. else
  4071. begin
  4072. if not(po_virtualmethod in tprocdef(proc.def).procoptions) then
  4073. begin
  4074. rttiList.concat(Tai_const_symbol.Createname(tprocdef(proc.def).mangledname));
  4075. typvalue:=1;
  4076. end
  4077. else
  4078. begin
  4079. { virtual method, write vmt offset }
  4080. rttiList.concat(Tai_const.Create_32bit(
  4081. tprocdef(proc.def)._class.vmtmethodoffset(tprocdef(proc.def).extnumber)));
  4082. typvalue:=2;
  4083. end;
  4084. end;
  4085. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4086. end;
  4087. begin
  4088. if needs_prop_entry(tsym(sym)) then
  4089. case tsym(sym).typ of
  4090. varsym:
  4091. begin
  4092. {$ifdef dummy}
  4093. if not(tvarsym(sym).vartype.def.deftype=objectdef) or
  4094. not(tobjectdef(tvarsym(sym).vartype.def).is_class) then
  4095. internalerror(1509992);
  4096. { access to implicit class property as field }
  4097. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4098. rttiList.concat(Tai_const_symbol.Createname(tvarsym(sym.vartype.def.get_rtti_label)));
  4099. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4100. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4101. { per default stored }
  4102. rttiList.concat(Tai_const.Create_32bit(1));
  4103. { index as well as ... }
  4104. rttiList.concat(Tai_const.Create_32bit(0));
  4105. { default value are zero }
  4106. rttiList.concat(Tai_const.Create_32bit(0));
  4107. rttiList.concat(Tai_const.Create_16bit(count));
  4108. inc(count);
  4109. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4110. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym.realname))));
  4111. rttiList.concat(Tai_string.Create(tvarsym(sym.realname)));
  4112. {$endif dummy}
  4113. end;
  4114. propertysym:
  4115. begin
  4116. if ppo_indexed in tpropertysym(sym).propoptions then
  4117. proctypesinfo:=$40
  4118. else
  4119. proctypesinfo:=0;
  4120. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti)));
  4121. writeproc(tpropertysym(sym).readaccess,0);
  4122. writeproc(tpropertysym(sym).writeaccess,2);
  4123. { isn't it stored ? }
  4124. if not(ppo_stored in tpropertysym(sym).propoptions) then
  4125. begin
  4126. rttiList.concat(Tai_const.Create_32bit(0));
  4127. proctypesinfo:=proctypesinfo or (3 shl 4);
  4128. end
  4129. else
  4130. writeproc(tpropertysym(sym).storedaccess,4);
  4131. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  4132. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  4133. rttiList.concat(Tai_const.Create_16bit(count));
  4134. inc(count);
  4135. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4136. rttiList.concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  4137. rttiList.concat(Tai_string.Create(tpropertysym(sym).realname));
  4138. end;
  4139. else internalerror(1509992);
  4140. end;
  4141. end;
  4142. procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem);
  4143. begin
  4144. if needs_prop_entry(tsym(sym)) then
  4145. begin
  4146. case tsym(sym).typ of
  4147. propertysym:
  4148. tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti);
  4149. else
  4150. internalerror(1509991);
  4151. end;
  4152. end;
  4153. end;
  4154. procedure tobjectdef.write_child_rtti_data(rt:trttitype);
  4155. begin
  4156. FRTTIType:=rt;
  4157. case rt of
  4158. initrtti :
  4159. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti);
  4160. fullrtti :
  4161. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
  4162. else
  4163. internalerror(200108301);
  4164. end;
  4165. end;
  4166. type
  4167. tclasslistitem = class(tlinkedlistitem)
  4168. index : longint;
  4169. p : tobjectdef;
  4170. end;
  4171. var
  4172. classtablelist : tlinkedlist;
  4173. tablecount : longint;
  4174. function searchclasstablelist(p : tobjectdef) : tclasslistitem;
  4175. var
  4176. hp : tclasslistitem;
  4177. begin
  4178. hp:=tclasslistitem(classtablelist.first);
  4179. while assigned(hp) do
  4180. if hp.p=p then
  4181. begin
  4182. searchclasstablelist:=hp;
  4183. exit;
  4184. end
  4185. else
  4186. hp:=tclasslistitem(hp.next);
  4187. searchclasstablelist:=nil;
  4188. end;
  4189. procedure tobjectdef.count_published_fields(sym:tnamedindexitem);
  4190. var
  4191. hp : tclasslistitem;
  4192. begin
  4193. if needs_prop_entry(tsym(sym)) and
  4194. (tsym(sym).typ=varsym) then
  4195. begin
  4196. if tvarsym(sym).vartype.def.deftype<>objectdef then
  4197. internalerror(0206001);
  4198. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4199. if not(assigned(hp)) then
  4200. begin
  4201. hp:=tclasslistitem.create;
  4202. hp.p:=tobjectdef(tvarsym(sym).vartype.def);
  4203. hp.index:=tablecount;
  4204. classtablelist.concat(hp);
  4205. inc(tablecount);
  4206. end;
  4207. inc(count);
  4208. end;
  4209. end;
  4210. procedure tobjectdef.writefields(sym:tnamedindexitem);
  4211. var
  4212. hp : tclasslistitem;
  4213. begin
  4214. if needs_prop_entry(tsym(sym)) and
  4215. (tsym(sym).typ=varsym) then
  4216. begin
  4217. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  4218. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4219. if not(assigned(hp)) then
  4220. internalerror(0206002);
  4221. rttiList.concat(Tai_const.Create_16bit(hp.index));
  4222. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym).realname)));
  4223. rttiList.concat(Tai_string.Create(tvarsym(sym).realname));
  4224. end;
  4225. end;
  4226. function tobjectdef.generate_field_table : tasmlabel;
  4227. var
  4228. fieldtable,
  4229. classtable : tasmlabel;
  4230. hp : tclasslistitem;
  4231. begin
  4232. classtablelist:=TLinkedList.Create;
  4233. getdatalabel(fieldtable);
  4234. getdatalabel(classtable);
  4235. count:=0;
  4236. tablecount:=0;
  4237. symtable.foreach({$ifdef FPC}@{$endif}count_published_fields);
  4238. if (cs_create_smart in aktmoduleswitches) then
  4239. rttiList.concat(Tai_cut.Create);
  4240. rttiList.concat(Tai_label.Create(fieldtable));
  4241. rttiList.concat(Tai_const.Create_16bit(count));
  4242. rttiList.concat(Tai_const_symbol.Create(classtable));
  4243. symtable.foreach({$ifdef FPC}@{$endif}writefields);
  4244. { generate the class table }
  4245. rttiList.concat(Tai_label.Create(classtable));
  4246. rttiList.concat(Tai_const.Create_16bit(tablecount));
  4247. hp:=tclasslistitem(classtablelist.first);
  4248. while assigned(hp) do
  4249. begin
  4250. rttiList.concat(Tai_const_symbol.Createname(tobjectdef(hp.p).vmt_mangledname));
  4251. hp:=tclasslistitem(hp.next);
  4252. end;
  4253. generate_field_table:=fieldtable;
  4254. classtablelist.free;
  4255. end;
  4256. function tobjectdef.next_free_name_index : longint;
  4257. var
  4258. i : longint;
  4259. begin
  4260. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4261. i:=childof.next_free_name_index
  4262. else
  4263. i:=0;
  4264. count:=0;
  4265. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4266. next_free_name_index:=i+count;
  4267. end;
  4268. procedure tobjectdef.write_rtti_data(rt:trttitype);
  4269. begin
  4270. case objecttype of
  4271. odt_class:
  4272. rttiList.concat(Tai_const.Create_8bit(tkclass));
  4273. odt_object:
  4274. rttiList.concat(Tai_const.Create_8bit(tkobject));
  4275. odt_interfacecom:
  4276. rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4277. odt_interfacecorba:
  4278. rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4279. else
  4280. exit;
  4281. end;
  4282. { generate the name }
  4283. rttiList.concat(Tai_const.Create_8bit(length(objname^)));
  4284. rttiList.concat(Tai_string.Create(objname^));
  4285. case rt of
  4286. initrtti :
  4287. begin
  4288. rttiList.concat(Tai_const.Create_32bit(size));
  4289. if objecttype in [odt_class,odt_object] then
  4290. begin
  4291. count:=0;
  4292. FRTTIType:=rt;
  4293. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti);
  4294. rttiList.concat(Tai_const.Create_32bit(count));
  4295. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
  4296. end;
  4297. end;
  4298. fullrtti :
  4299. begin
  4300. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4301. rttiList.concat(Tai_const.Create_32bit(0))
  4302. else
  4303. rttiList.concat(Tai_const_symbol.Createname(vmt_mangledname));
  4304. { write owner typeinfo }
  4305. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4306. rttiList.concat(Tai_const_symbol.Create(childof.get_rtti_label(fullrtti)))
  4307. else
  4308. rttiList.concat(Tai_const.Create_32bit(0));
  4309. { count total number of properties }
  4310. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4311. count:=childof.next_free_name_index
  4312. else
  4313. count:=0;
  4314. { write it }
  4315. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4316. rttiList.concat(Tai_const.Create_16bit(count));
  4317. { write unit name }
  4318. rttiList.concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4319. rttiList.concat(Tai_string.Create(current_module.realmodulename^));
  4320. { write published properties count }
  4321. count:=0;
  4322. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4323. rttiList.concat(Tai_const.Create_16bit(count));
  4324. { count is used to write nameindex }
  4325. { but we need an offset of the owner }
  4326. { to give each property an own slot }
  4327. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4328. count:=childof.next_free_name_index
  4329. else
  4330. count:=0;
  4331. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
  4332. end;
  4333. end;
  4334. end;
  4335. function tobjectdef.is_publishable : boolean;
  4336. begin
  4337. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4338. end;
  4339. {****************************************************************************
  4340. TIMPLEMENTEDINTERFACES
  4341. ****************************************************************************}
  4342. type
  4343. tnamemap = class(TNamedIndexItem)
  4344. newname: pstring;
  4345. constructor create(const aname, anewname: string);
  4346. destructor destroy; override;
  4347. end;
  4348. constructor tnamemap.create(const aname, anewname: string);
  4349. begin
  4350. inherited createname(name);
  4351. newname:=stringdup(anewname);
  4352. end;
  4353. destructor tnamemap.destroy;
  4354. begin
  4355. stringdispose(newname);
  4356. inherited destroy;
  4357. end;
  4358. type
  4359. tprocdefstore = class(TNamedIndexItem)
  4360. procdef: tprocdef;
  4361. constructor create(aprocdef: tprocdef);
  4362. end;
  4363. constructor tprocdefstore.create(aprocdef: tprocdef);
  4364. begin
  4365. inherited create;
  4366. procdef:=aprocdef;
  4367. end;
  4368. type
  4369. timplintfentry = class(TNamedIndexItem)
  4370. intf: tobjectdef;
  4371. ioffs: longint;
  4372. namemappings: tdictionary;
  4373. procdefs: TIndexArray;
  4374. constructor create(aintf: tobjectdef);
  4375. destructor destroy; override;
  4376. end;
  4377. constructor timplintfentry.create(aintf: tobjectdef);
  4378. begin
  4379. inherited create;
  4380. intf:=aintf;
  4381. ioffs:=-1;
  4382. namemappings:=nil;
  4383. procdefs:=nil;
  4384. end;
  4385. destructor timplintfentry.destroy;
  4386. begin
  4387. if assigned(namemappings) then
  4388. namemappings.free;
  4389. if assigned(procdefs) then
  4390. procdefs.free;
  4391. inherited destroy;
  4392. end;
  4393. constructor timplementedinterfaces.create;
  4394. begin
  4395. finterfaces:=tindexarray.create(1);
  4396. end;
  4397. destructor timplementedinterfaces.destroy;
  4398. begin
  4399. finterfaces.destroy;
  4400. end;
  4401. function timplementedinterfaces.count: longint;
  4402. begin
  4403. count:=finterfaces.count;
  4404. end;
  4405. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4406. begin
  4407. if (intfindex<1) or (intfindex>count) then
  4408. InternalError(200006123);
  4409. end;
  4410. function timplementedinterfaces.interfaces(intfindex: longint): tobjectdef;
  4411. begin
  4412. checkindex(intfindex);
  4413. interfaces:=timplintfentry(finterfaces.search(intfindex)).intf;
  4414. end;
  4415. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4416. begin
  4417. checkindex(intfindex);
  4418. ioffsets:=@timplintfentry(finterfaces.search(intfindex)).ioffs;
  4419. end;
  4420. function timplementedinterfaces.searchintf(def: tdef): longint;
  4421. var
  4422. i: longint;
  4423. begin
  4424. i:=1;
  4425. while (i<=count) and (tdef(interfaces(i))<>def) do inc(i);
  4426. if i<=count then
  4427. searchintf:=i
  4428. else
  4429. searchintf:=-1;
  4430. end;
  4431. procedure timplementedinterfaces.deref;
  4432. var
  4433. i: longint;
  4434. begin
  4435. for i:=1 to count do
  4436. with timplintfentry(finterfaces.search(i)) do
  4437. resolvedef(tdef(intf));
  4438. end;
  4439. procedure timplementedinterfaces.addintfref(def: tdef);
  4440. begin
  4441. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4442. end;
  4443. procedure timplementedinterfaces.addintf(def: tdef);
  4444. begin
  4445. if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or
  4446. not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4447. internalerror(200006124);
  4448. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4449. end;
  4450. procedure timplementedinterfaces.clearmappings;
  4451. var
  4452. i: longint;
  4453. begin
  4454. for i:=1 to count do
  4455. with timplintfentry(finterfaces.search(i)) do
  4456. begin
  4457. if assigned(namemappings) then
  4458. namemappings.free;
  4459. namemappings:=nil;
  4460. end;
  4461. end;
  4462. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4463. begin
  4464. checkindex(intfindex);
  4465. with timplintfentry(finterfaces.search(intfindex)) do
  4466. begin
  4467. if not assigned(namemappings) then
  4468. namemappings:=tdictionary.create;
  4469. namemappings.insert(tnamemap.create(name,newname));
  4470. end;
  4471. end;
  4472. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4473. begin
  4474. checkindex(intfindex);
  4475. if not assigned(nextexist) then
  4476. with timplintfentry(finterfaces.search(intfindex)) do
  4477. begin
  4478. if assigned(namemappings) then
  4479. nextexist:=namemappings.search(name)
  4480. else
  4481. nextexist:=nil;
  4482. end;
  4483. if assigned(nextexist) then
  4484. begin
  4485. getmappings:=tnamemap(nextexist).newname^;
  4486. nextexist:=tnamemap(nextexist).listnext;
  4487. end
  4488. else
  4489. getmappings:='';
  4490. end;
  4491. procedure timplementedinterfaces.clearimplprocs;
  4492. var
  4493. i: longint;
  4494. begin
  4495. for i:=1 to count do
  4496. with timplintfentry(finterfaces.search(i)) do
  4497. begin
  4498. if assigned(procdefs) then
  4499. procdefs.free;
  4500. procdefs:=nil;
  4501. end;
  4502. end;
  4503. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef);
  4504. begin
  4505. checkindex(intfindex);
  4506. with timplintfentry(finterfaces.search(intfindex)) do
  4507. begin
  4508. if not assigned(procdefs) then
  4509. procdefs:=tindexarray.create(4);
  4510. procdefs.insert(tprocdefstore.create(procdef));
  4511. end;
  4512. end;
  4513. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4514. begin
  4515. checkindex(intfindex);
  4516. with timplintfentry(finterfaces.search(intfindex)) do
  4517. if assigned(procdefs) then
  4518. implproccount:=procdefs.count
  4519. else
  4520. implproccount:=0;
  4521. end;
  4522. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef;
  4523. begin
  4524. checkindex(intfindex);
  4525. with timplintfentry(finterfaces.search(intfindex)) do
  4526. if assigned(procdefs) then
  4527. implprocs:=tprocdefstore(procdefs.search(procindex)).procdef
  4528. else
  4529. internalerror(200006131);
  4530. end;
  4531. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4532. var
  4533. possible: boolean;
  4534. i: longint;
  4535. iiep1: TIndexArray;
  4536. iiep2: TIndexArray;
  4537. begin
  4538. checkindex(intfindex);
  4539. checkindex(remainindex);
  4540. iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs;
  4541. iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs;
  4542. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4543. begin
  4544. possible:=true;
  4545. weight:=0;
  4546. end
  4547. else
  4548. begin
  4549. possible:=assigned(iiep2) and (iiep1.count<=iiep2.count);
  4550. i:=1;
  4551. while (possible) and (i<=iiep1.count) do
  4552. begin
  4553. possible:=
  4554. (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef);
  4555. inc(i);
  4556. end;
  4557. if possible then
  4558. weight:=iiep1.count;
  4559. end;
  4560. isimplmergepossible:=possible;
  4561. end;
  4562. {****************************************************************************
  4563. TFORWARDDEF
  4564. ****************************************************************************}
  4565. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  4566. var
  4567. oldregisterdef : boolean;
  4568. begin
  4569. { never register the forwarddefs, they are disposed at the
  4570. end of the type declaration block }
  4571. oldregisterdef:=registerdef;
  4572. registerdef:=false;
  4573. inherited create;
  4574. registerdef:=oldregisterdef;
  4575. deftype:=forwarddef;
  4576. tosymname:=s;
  4577. forwardpos:=pos;
  4578. end;
  4579. function tforwarddef.gettypename:string;
  4580. begin
  4581. gettypename:='unresolved forward to '+tosymname;
  4582. end;
  4583. {****************************************************************************
  4584. TERRORDEF
  4585. ****************************************************************************}
  4586. constructor terrordef.create;
  4587. begin
  4588. inherited create;
  4589. deftype:=errordef;
  4590. end;
  4591. {$ifdef GDB}
  4592. function terrordef.stabstring : pchar;
  4593. begin
  4594. stabstring:=strpnew('error'+numberstring);
  4595. end;
  4596. {$endif GDB}
  4597. function terrordef.gettypename:string;
  4598. begin
  4599. gettypename:='<erroneous type>';
  4600. end;
  4601. {****************************************************************************
  4602. GDB Helpers
  4603. ****************************************************************************}
  4604. {$ifdef GDB}
  4605. function typeglobalnumber(const s : string) : string;
  4606. var st : string;
  4607. symt : tsymtable;
  4608. srsym : tsym;
  4609. srsymtable : tsymtable;
  4610. old_make_ref : boolean;
  4611. begin
  4612. old_make_ref:=make_ref;
  4613. make_ref:=false;
  4614. typeglobalnumber := '0';
  4615. srsym := nil;
  4616. if pos('.',s) > 0 then
  4617. begin
  4618. st := copy(s,1,pos('.',s)-1);
  4619. searchsym(st,srsym,srsymtable);
  4620. st := copy(s,pos('.',s)+1,255);
  4621. if assigned(srsym) then
  4622. begin
  4623. if srsym.typ = unitsym then
  4624. begin
  4625. symt := tunitsym(srsym).unitsymtable;
  4626. srsym := tsym(symt.search(st));
  4627. end else srsym := nil;
  4628. end;
  4629. end else st := s;
  4630. if srsym = nil then
  4631. searchsym(st,srsym,srsymtable);
  4632. if (srsym=nil) or
  4633. (srsym.typ<>typesym) then
  4634. begin
  4635. Message(type_e_type_id_expected);
  4636. exit;
  4637. end;
  4638. typeglobalnumber := tstoreddef(ttypesym(srsym).restype.def).numberstring;
  4639. make_ref:=old_make_ref;
  4640. end;
  4641. {$endif GDB}
  4642. {****************************************************************************
  4643. Definition Helpers
  4644. ****************************************************************************}
  4645. procedure reset_global_defs;
  4646. var
  4647. def : tstoreddef;
  4648. {$ifdef debug}
  4649. prevdef : tstoreddef;
  4650. {$endif debug}
  4651. begin
  4652. {$ifdef debug}
  4653. prevdef:=nil;
  4654. {$endif debug}
  4655. {$ifdef GDB}
  4656. pglobaltypecount:=@globaltypecount;
  4657. {$endif GDB}
  4658. def:=firstglobaldef;
  4659. while assigned(def) do
  4660. begin
  4661. {$ifdef GDB}
  4662. if assigned(def.typesym) then
  4663. ttypesym(def.typesym).isusedinstab:=false;
  4664. def.is_def_stab_written:=not_written;
  4665. {$endif GDB}
  4666. { reset rangenr's }
  4667. case def.deftype of
  4668. orddef : torddef(def).rangenr:=0;
  4669. enumdef : tenumdef(def).rangenr:=0;
  4670. arraydef : tarraydef(def).rangenr:=0;
  4671. end;
  4672. if assigned(def.rttitablesym) then
  4673. trttisym(def.rttitablesym).lab := nil;
  4674. if assigned(def.inittablesym) then
  4675. trttisym(def.inittablesym).lab := nil;
  4676. def.localrttilab[initrtti]:=nil;
  4677. def.localrttilab[fullrtti]:=nil;
  4678. {$ifdef debug}
  4679. prevdef:=def;
  4680. {$endif debug}
  4681. def:=def.nextglobal;
  4682. end;
  4683. end;
  4684. function is_interfacecom(def: tdef): boolean;
  4685. begin
  4686. is_interfacecom:=
  4687. assigned(def) and
  4688. (def.deftype=objectdef) and
  4689. (tobjectdef(def).objecttype=odt_interfacecom);
  4690. end;
  4691. function is_interfacecorba(def: tdef): boolean;
  4692. begin
  4693. is_interfacecorba:=
  4694. assigned(def) and
  4695. (def.deftype=objectdef) and
  4696. (tobjectdef(def).objecttype=odt_interfacecorba);
  4697. end;
  4698. function is_interface(def: tdef): boolean;
  4699. begin
  4700. is_interface:=
  4701. assigned(def) and
  4702. (def.deftype=objectdef) and
  4703. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  4704. end;
  4705. function is_class(def: tdef): boolean;
  4706. begin
  4707. is_class:=
  4708. assigned(def) and
  4709. (def.deftype=objectdef) and
  4710. (tobjectdef(def).objecttype=odt_class);
  4711. end;
  4712. function is_object(def: tdef): boolean;
  4713. begin
  4714. is_object:=
  4715. assigned(def) and
  4716. (def.deftype=objectdef) and
  4717. (tobjectdef(def).objecttype=odt_object);
  4718. end;
  4719. function is_cppclass(def: tdef): boolean;
  4720. begin
  4721. is_cppclass:=
  4722. assigned(def) and
  4723. (def.deftype=objectdef) and
  4724. (tobjectdef(def).objecttype=odt_cppclass);
  4725. end;
  4726. function is_class_or_interface(def: tdef): boolean;
  4727. begin
  4728. is_class_or_interface:=
  4729. assigned(def) and
  4730. (def.deftype=objectdef) and
  4731. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4732. end;
  4733. end.
  4734. {
  4735. $Log$
  4736. Revision 1.55 2001-11-02 22:58:06 peter
  4737. * procsym definition rewrite
  4738. Revision 1.54 2001/10/25 21:22:37 peter
  4739. * calling convention rewrite
  4740. Revision 1.53 2001/10/20 17:21:54 peter
  4741. * fixed size of constset when change from small to normalset
  4742. Revision 1.52 2001/10/15 13:16:26 jonas
  4743. * better size checking of data (now an error is returned for
  4744. "array[longint] of longint") ("merged")
  4745. Revision 1.51 2001/09/19 11:04:42 michael
  4746. * Smartlinking with interfaces fixed
  4747. * Better smartlinking for rtti and init tables
  4748. Revision 1.50 2001/09/17 21:29:12 peter
  4749. * merged netbsd, fpu-overflow from fixes branch
  4750. Revision 1.49 2001/09/10 10:26:27 jonas
  4751. * fixed web bug 1593
  4752. * writing of procvar headers is more complete (mention var/const/out for
  4753. paras, add "of object" if applicable)
  4754. + error if declaring explicit self para as var/const
  4755. * fixed mangled name of procedures which contain an explicit self para
  4756. * parsing para's should be slightly faster because mangled name of
  4757. procedure is only updated once instead of after parsing each para
  4758. (all merged from fixes)
  4759. Revision 1.48 2001/09/03 15:18:38 jonas
  4760. * aded missing reset of labels of rttitablesym and inittablesym labels
  4761. Revision 1.47 2001/09/02 21:18:28 peter
  4762. * split constsym.value in valueord,valueordptr,valueptr. The valueordptr
  4763. is used for holding target platform pointer values. As those can be
  4764. bigger than the source platform.
  4765. Revision 1.46 2001/08/30 20:13:54 peter
  4766. * rtti/init table updates
  4767. * rttisym for reusable global rtti/init info
  4768. * support published for interfaces
  4769. Revision 1.45 2001/08/26 13:36:49 florian
  4770. * some cg reorganisation
  4771. * some PPC updates
  4772. Revision 1.44 2001/08/22 21:16:22 florian
  4773. * some interfaces related problems regarding
  4774. mapping of interface implementions fixed
  4775. Revision 1.43 2001/08/19 09:39:27 peter
  4776. * local browser support fixed
  4777. Revision 1.41 2001/08/12 20:04:33 peter
  4778. * fpu_used=0 when simplify_ppu is used
  4779. * small crc updating fixes for tprocdef
  4780. Revision 1.40 2001/08/06 21:40:48 peter
  4781. * funcret moved from tprocinfo to tprocdef
  4782. Revision 1.39 2001/08/01 21:47:48 peter
  4783. * fixed passing of array of record or shortstring to open array
  4784. Revision 1.38 2001/07/30 20:59:27 peter
  4785. * m68k updates from v10 merged
  4786. Revision 1.37 2001/07/30 11:52:57 jonas
  4787. * fixed web bugs 1563/1564: procvars of object can't be regvars (merged)
  4788. Revision 1.36 2001/07/01 20:16:16 peter
  4789. * alignmentinfo record added
  4790. * -Oa argument supports more alignment settings that can be specified
  4791. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  4792. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  4793. required alignment and the maximum usefull alignment. The final
  4794. alignment will be choosen per variable size dependent on these
  4795. settings
  4796. Revision 1.35 2001/06/27 21:37:36 peter
  4797. * v10 merges
  4798. Revision 1.34 2001/06/04 18:05:39 peter
  4799. * procdef demangling fixed
  4800. Revision 1.33 2001/06/04 11:53:13 peter
  4801. + varargs directive
  4802. Revision 1.32 2001/05/09 19:58:45 peter
  4803. * m68k doesn't support double (merged)
  4804. Revision 1.31 2001/05/06 14:49:17 peter
  4805. * ppu object to class rewrite
  4806. * move ppu read and write stuff to fppu
  4807. Revision 1.30 2001/04/22 22:46:49 florian
  4808. * more variant support
  4809. Revision 1.29 2001/04/21 12:03:12 peter
  4810. * m68k updates merged from fixes branch
  4811. Revision 1.28 2001/04/18 22:01:58 peter
  4812. * registration of targets and assemblers
  4813. Revision 1.27 2001/04/13 01:22:15 peter
  4814. * symtable change to classes
  4815. * range check generation and errors fixed, make cycle DEBUG=1 works
  4816. * memory leaks fixed
  4817. Revision 1.26 2001/04/05 21:32:22 peter
  4818. * enum stabs fix (merged)
  4819. Revision 1.25 2001/04/04 21:30:45 florian
  4820. * applied several fixes to get the DD8 Delphi Unit compiled
  4821. e.g. "forward"-interfaces are working now
  4822. Revision 1.24 2001/04/02 21:20:34 peter
  4823. * resulttype rewrite
  4824. Revision 1.23 2001/03/22 23:28:39 florian
  4825. * correct initialisation of rec_tguid when loading the system unit
  4826. Revision 1.22 2001/03/22 00:10:58 florian
  4827. + basic variant type support in the compiler
  4828. Revision 1.21 2001/03/11 22:58:50 peter
  4829. * getsym redesign, removed the globals srsym,srsymtable
  4830. Revision 1.20 2001/01/06 20:11:29 peter
  4831. * merged c packrecords fix
  4832. Revision 1.19 2000/12/25 00:07:29 peter
  4833. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  4834. tlinkedlist objects)
  4835. Revision 1.18 2000/12/24 12:20:45 peter
  4836. * classes, enum stabs fixes merged from 1.0.x
  4837. Revision 1.17 2000/12/07 17:19:43 jonas
  4838. * new constant handling: from now on, hex constants >$7fffffff are
  4839. parsed as unsigned constants (otherwise, $80000000 got sign extended
  4840. and became $ffffffff80000000), all constants in the longint range
  4841. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  4842. are cardinals and the rest are int64's.
  4843. * added lots of longint typecast to prevent range check errors in the
  4844. compiler and rtl
  4845. * type casts of symbolic ordinal constants are now preserved
  4846. * fixed bug where the original resulttype.def wasn't restored correctly
  4847. after doing a 64bit rangecheck
  4848. Revision 1.16 2000/11/30 23:12:57 florian
  4849. * if raw interfaces inherit from IUnknown they are ref. counted too
  4850. Revision 1.15 2000/11/29 00:30:40 florian
  4851. * unused units removed from uses clause
  4852. * some changes for widestrings
  4853. Revision 1.14 2000/11/28 00:28:06 pierre
  4854. * stabs fixing
  4855. Revision 1.13 2000/11/26 18:09:40 florian
  4856. * fixed rtti for chars
  4857. Revision 1.12 2000/11/19 16:23:35 florian
  4858. *** empty log message ***
  4859. Revision 1.11 2000/11/12 23:24:12 florian
  4860. * interfaces are basically running
  4861. Revision 1.10 2000/11/11 16:12:38 peter
  4862. * add far; to typename for far pointer
  4863. Revision 1.9 2000/11/07 20:01:57 peter
  4864. * fix vmt index for classes
  4865. Revision 1.8 2000/11/06 23:13:53 peter
  4866. * uppercase manglednames
  4867. Revision 1.7 2000/11/06 23:11:38 florian
  4868. * writeln debugger uninstalled ;)
  4869. Revision 1.6 2000/11/06 23:05:52 florian
  4870. * more fixes
  4871. Revision 1.5 2000/11/06 20:30:55 peter
  4872. * more fixes to get make cycle working
  4873. Revision 1.4 2000/11/04 14:25:22 florian
  4874. + merged Attila's changes for interfaces, not tested yet
  4875. Revision 1.3 2000/11/02 12:04:10 pierre
  4876. * remove RecOffset code, that created problems
  4877. Revision 1.2 2000/11/01 23:04:38 peter
  4878. * tprocdef.fullprocname added for better casesensitve writing of
  4879. procedures
  4880. Revision 1.1 2000/10/31 22:02:52 peter
  4881. * symtable splitted, no real code changes
  4882. }