symdef.pas 175 KB

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