symdef.pas 176 KB

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