symdef.pas 172 KB

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