2
0

symdef.pas 163 KB

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