symdef.inc 120 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {****************************************************************************
  19. TDEF (base class for definitions)
  20. ****************************************************************************}
  21. const
  22. { if you change one of the following contants, }
  23. { you have also to change the typinfo unit }
  24. { and the rtl/i386,template/rttip.inc files }
  25. tkUnknown = 0;
  26. tkInteger = 1;
  27. tkChar = 2;
  28. tkEnumeration = 3;
  29. tkFloat = 4;
  30. tkSet = 5;
  31. tkMethod = 6;
  32. tkSString = 7;
  33. tkString = tkSString;
  34. tkLString = 8;
  35. tkAString = 9;
  36. tkWString = 10;
  37. tkVariant = 11;
  38. tkArray = 12;
  39. tkRecord = 13;
  40. tkInterface = 14;
  41. tkClass = 15;
  42. tkObject = 16;
  43. tkWChar = 17;
  44. tkBool = 18;
  45. otSByte = 0;
  46. otUByte = 1;
  47. otSWord = 2;
  48. otUWord = 3;
  49. otSLong = 4;
  50. otULong = 5;
  51. ftSingle = 0;
  52. ftDouble = 1;
  53. ftExtended = 2;
  54. ftComp = 3;
  55. ftCurr = 4;
  56. ftFixed16 = 5;
  57. ftFixed32 = 6;
  58. mkProcedure = 0;
  59. mkFunction = 1;
  60. mkConstructor = 2;
  61. mkDestructor = 3;
  62. mkClassProcedure= 4;
  63. mkClassFunction = 5;
  64. pfvar = 1;
  65. pfConst = 2;
  66. pfArray = 4;
  67. pfAddress = 8;
  68. pfReference = 16;
  69. pfOut = 32;
  70. constructor tdef.init;
  71. begin
  72. inherited init;
  73. deftype:=abstractdef;
  74. owner := nil;
  75. typesym := nil;
  76. savesize := 0;
  77. if registerdef then
  78. symtablestack^.registerdef(@self);
  79. has_rtti:=false;
  80. has_inittable:=false;
  81. {$ifdef GDB}
  82. is_def_stab_written := false;
  83. globalnb := 0;
  84. {$endif GDB}
  85. if assigned(lastglobaldef) then
  86. begin
  87. lastglobaldef^.nextglobal := @self;
  88. previousglobal:=lastglobaldef;
  89. end
  90. else
  91. begin
  92. firstglobaldef := @self;
  93. previousglobal := nil;
  94. end;
  95. lastglobaldef := @self;
  96. nextglobal := nil;
  97. end;
  98. constructor tdef.load;
  99. begin
  100. deftype:=abstractdef;
  101. next := nil;
  102. owner := nil;
  103. has_rtti:=false;
  104. has_inittable:=false;
  105. {$ifdef GDB}
  106. is_def_stab_written := false;
  107. globalnb := 0;
  108. {$endif GDB}
  109. if assigned(lastglobaldef) then
  110. begin
  111. lastglobaldef^.nextglobal := @self;
  112. previousglobal:=lastglobaldef;
  113. end
  114. else
  115. begin
  116. firstglobaldef := @self;
  117. previousglobal:=nil;
  118. end;
  119. lastglobaldef := @self;
  120. nextglobal := nil;
  121. { load }
  122. indexnr:=readword;
  123. typesym:=ptypesym(readsymref);
  124. end;
  125. destructor tdef.done;
  126. begin
  127. { first element ? }
  128. if not(assigned(previousglobal)) then
  129. begin
  130. firstglobaldef := nextglobal;
  131. if assigned(firstglobaldef) then
  132. firstglobaldef^.previousglobal:=nil;
  133. end
  134. else
  135. begin
  136. { remove reference in the element before }
  137. previousglobal^.nextglobal:=nextglobal;
  138. end;
  139. { last element ? }
  140. if not(assigned(nextglobal)) then
  141. begin
  142. lastglobaldef := previousglobal;
  143. if assigned(lastglobaldef) then
  144. lastglobaldef^.nextglobal:=nil;
  145. end
  146. else
  147. nextglobal^.previousglobal:=previousglobal;
  148. previousglobal:=nil;
  149. nextglobal:=nil;
  150. {$ifdef SYNONYM}
  151. while assigned(typesym) do
  152. begin
  153. typesym^.restype.setdef(nil);
  154. typesym:=typesym^.synonym;
  155. end;
  156. {$endif}
  157. end;
  158. { used for enumdef because the symbols are
  159. inserted in the owner symtable }
  160. procedure tdef.correct_owner_symtable;
  161. var
  162. st : psymtable;
  163. begin
  164. if assigned(owner) and
  165. (owner^.symtabletype in [recordsymtable,objectsymtable]) then
  166. begin
  167. owner^.defindex^.deleteindex(@self);
  168. st:=owner;
  169. while (st^.symtabletype in [recordsymtable,objectsymtable]) do
  170. st:=st^.next;
  171. st^.registerdef(@self);
  172. end;
  173. end;
  174. function tdef.typename:string;
  175. begin
  176. if assigned(typesym) then
  177. typename:=Upper(typesym^.name)
  178. else
  179. typename:=gettypename;
  180. end;
  181. function tdef.gettypename : string;
  182. begin
  183. gettypename:='<unknown type>'
  184. end;
  185. function tdef.is_in_current : boolean;
  186. var
  187. p : psymtable;
  188. begin
  189. p:=owner;
  190. is_in_current:=false;
  191. while assigned(p) do
  192. begin
  193. if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
  194. or (p^.symtabletype in [globalsymtable,staticsymtable]) then
  195. begin
  196. is_in_current:=true;
  197. exit;
  198. end
  199. else if p^.symtabletype in [localsymtable,parasymtable,objectsymtable] then
  200. begin
  201. if assigned(p^.defowner) then
  202. p:=pobjectdef(p^.defowner)^.owner
  203. else
  204. exit;
  205. end
  206. else
  207. exit;
  208. end;
  209. end;
  210. procedure tdef.write;
  211. begin
  212. writeword(indexnr);
  213. writesymref(typesym);
  214. {$ifdef GDB}
  215. if globalnb = 0 then
  216. begin
  217. if assigned(owner) then
  218. globalnb := owner^.getnewtypecount
  219. else
  220. begin
  221. globalnb := PGlobalTypeCount^;
  222. Inc(PGlobalTypeCount^);
  223. end;
  224. end;
  225. {$endif GDB}
  226. end;
  227. function tdef.size : longint;
  228. begin
  229. size:=savesize;
  230. end;
  231. function tdef.alignment : longint;
  232. begin
  233. { normal alignment by default }
  234. alignment:=0;
  235. end;
  236. {$ifdef GDB}
  237. procedure tdef.set_globalnb;
  238. begin
  239. globalnb :=PGlobalTypeCount^;
  240. inc(PglobalTypeCount^);
  241. end;
  242. function tdef.stabstring : pchar;
  243. begin
  244. stabstring := strpnew('t'+numberstring+';');
  245. end;
  246. function tdef.numberstring : string;
  247. var table : psymtable;
  248. begin
  249. {formal def have no type !}
  250. if deftype = formaldef then
  251. begin
  252. numberstring := voiddef^.numberstring;
  253. exit;
  254. end;
  255. if (not assigned(typesym)) or (not typesym^.isusedinstab) then
  256. begin
  257. {set even if debuglist is not defined}
  258. if assigned(typesym) then
  259. typesym^.isusedinstab := true;
  260. if assigned(debuglist) and not is_def_stab_written then
  261. concatstabto(debuglist);
  262. end;
  263. if not (cs_gdb_dbx in aktglobalswitches) then
  264. begin
  265. if globalnb = 0 then
  266. set_globalnb;
  267. numberstring := tostr(globalnb);
  268. end
  269. else
  270. begin
  271. if globalnb = 0 then
  272. begin
  273. if assigned(owner) then
  274. globalnb := owner^.getnewtypecount
  275. else
  276. begin
  277. globalnb := PGlobalTypeCount^;
  278. Inc(PGlobalTypeCount^);
  279. end;
  280. end;
  281. if assigned(typesym) then
  282. begin
  283. table := typesym^.owner;
  284. if table^.unitid > 0 then
  285. numberstring := '('+tostr(table^.unitid)+','+tostr(typesym^.restype.def^.globalnb)+')'
  286. else
  287. numberstring := tostr(globalnb);
  288. exit;
  289. end;
  290. numberstring := tostr(globalnb);
  291. end;
  292. end;
  293. function tdef.allstabstring : pchar;
  294. var stabchar : string[2];
  295. ss,st : pchar;
  296. sname : string;
  297. sym_line_no : longint;
  298. begin
  299. ss := stabstring;
  300. getmem(st,strlen(ss)+512);
  301. stabchar := 't';
  302. if deftype in tagtypes then
  303. stabchar := 'Tt';
  304. if assigned(typesym) then
  305. begin
  306. sname := typesym^.name;
  307. sym_line_no:=typesym^.fileinfo.line;
  308. end
  309. else
  310. begin
  311. sname := ' ';
  312. sym_line_no:=0;
  313. end;
  314. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  315. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  316. allstabstring := strnew(st);
  317. freemem(st,strlen(ss)+512);
  318. strdispose(ss);
  319. end;
  320. procedure tdef.concatstabto(asmlist : paasmoutput);
  321. var stab_str : pchar;
  322. begin
  323. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  324. and not is_def_stab_written then
  325. begin
  326. If cs_gdb_dbx in aktglobalswitches then
  327. begin
  328. { otherwise you get two of each def }
  329. If assigned(typesym) then
  330. begin
  331. if typesym^.typ=symconst.typesym then
  332. typesym^.isusedinstab:=true;
  333. if (typesym^.owner = nil) or
  334. ((typesym^.owner^.symtabletype = unitsymtable) and
  335. punitsymtable(typesym^.owner)^.dbx_count_ok) then
  336. begin
  337. {with DBX we get the definition from the other objects }
  338. is_def_stab_written := true;
  339. exit;
  340. end;
  341. end;
  342. end;
  343. { to avoid infinite loops }
  344. is_def_stab_written := true;
  345. stab_str := allstabstring;
  346. asmlist^.concat(new(pai_stabs,init(stab_str)));
  347. end;
  348. end;
  349. {$endif GDB}
  350. procedure tdef.deref;
  351. begin
  352. resolvesym(psym(typesym));
  353. end;
  354. { rtti generation }
  355. procedure tdef.generate_rtti;
  356. begin
  357. if not has_rtti then
  358. begin
  359. has_rtti:=true;
  360. getdatalabel(rtti_label);
  361. write_child_rtti_data;
  362. rttilist^.concat(new(pai_symbol,init(rtti_label,0)));
  363. write_rtti_data;
  364. rttilist^.concat(new(pai_symbol_end,init(rtti_label)));
  365. end;
  366. end;
  367. function tdef.get_rtti_label : string;
  368. begin
  369. generate_rtti;
  370. get_rtti_label:=rtti_label^.name;
  371. end;
  372. { init table handling }
  373. function tdef.needs_inittable : boolean;
  374. begin
  375. needs_inittable:=false;
  376. end;
  377. procedure tdef.generate_inittable;
  378. begin
  379. has_inittable:=true;
  380. getdatalabel(inittable_label);
  381. write_child_init_data;
  382. rttilist^.concat(new(pai_label,init(inittable_label)));
  383. write_init_data;
  384. end;
  385. procedure tdef.write_init_data;
  386. begin
  387. write_rtti_data;
  388. end;
  389. procedure tdef.write_child_init_data;
  390. begin
  391. write_child_rtti_data;
  392. end;
  393. function tdef.get_inittable_label : pasmlabel;
  394. begin
  395. if not(has_inittable) then
  396. generate_inittable;
  397. get_inittable_label:=inittable_label;
  398. end;
  399. procedure tdef.write_rtti_name;
  400. var
  401. str : string;
  402. begin
  403. { name }
  404. if assigned(typesym) then
  405. begin
  406. str:=typesym^.name;
  407. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  408. end
  409. else
  410. rttilist^.concat(new(pai_string,init(#0)))
  411. end;
  412. { returns true, if the definition can be published }
  413. function tdef.is_publishable : boolean;
  414. begin
  415. is_publishable:=false;
  416. end;
  417. procedure tdef.write_rtti_data;
  418. begin
  419. end;
  420. procedure tdef.write_child_rtti_data;
  421. begin
  422. end;
  423. function tdef.is_intregable : boolean;
  424. begin
  425. is_intregable:=false;
  426. case deftype of
  427. pointerdef,
  428. enumdef,
  429. procvardef :
  430. is_intregable:=true;
  431. orddef :
  432. case porddef(@self)^.typ of
  433. bool8bit,bool16bit,bool32bit,
  434. u8bit,u16bit,u32bit,
  435. s8bit,s16bit,s32bit:
  436. is_intregable:=true;
  437. end;
  438. setdef:
  439. is_intregable:=is_smallset(@self);
  440. end;
  441. end;
  442. function tdef.is_fpuregable : boolean;
  443. begin
  444. is_fpuregable:=(deftype=floatdef) and not(pfloatdef(@self)^.typ in [f32bit,f16bit]);
  445. end;
  446. {****************************************************************************
  447. TSTRINGDEF
  448. ****************************************************************************}
  449. constructor tstringdef.shortinit(l : byte);
  450. begin
  451. tdef.init;
  452. string_typ:=st_shortstring;
  453. deftype:=stringdef;
  454. len:=l;
  455. savesize:=len+1;
  456. end;
  457. constructor tstringdef.shortload;
  458. begin
  459. tdef.load;
  460. string_typ:=st_shortstring;
  461. deftype:=stringdef;
  462. len:=readbyte;
  463. savesize:=len+1;
  464. end;
  465. constructor tstringdef.longinit(l : longint);
  466. begin
  467. tdef.init;
  468. string_typ:=st_longstring;
  469. deftype:=stringdef;
  470. len:=l;
  471. savesize:=target_os.size_of_pointer;
  472. end;
  473. constructor tstringdef.longload;
  474. begin
  475. tdef.load;
  476. deftype:=stringdef;
  477. string_typ:=st_longstring;
  478. len:=readlong;
  479. savesize:=target_os.size_of_pointer;
  480. end;
  481. constructor tstringdef.ansiinit(l : longint);
  482. begin
  483. tdef.init;
  484. string_typ:=st_ansistring;
  485. deftype:=stringdef;
  486. len:=l;
  487. savesize:=target_os.size_of_pointer;
  488. end;
  489. constructor tstringdef.ansiload;
  490. begin
  491. tdef.load;
  492. deftype:=stringdef;
  493. string_typ:=st_ansistring;
  494. len:=readlong;
  495. savesize:=target_os.size_of_pointer;
  496. end;
  497. constructor tstringdef.wideinit(l : longint);
  498. begin
  499. tdef.init;
  500. string_typ:=st_widestring;
  501. deftype:=stringdef;
  502. len:=l;
  503. savesize:=target_os.size_of_pointer;
  504. end;
  505. constructor tstringdef.wideload;
  506. begin
  507. tdef.load;
  508. deftype:=stringdef;
  509. string_typ:=st_widestring;
  510. len:=readlong;
  511. savesize:=target_os.size_of_pointer;
  512. end;
  513. function tstringdef.stringtypname:string;
  514. const
  515. typname:array[tstringtype] of string[8]=('',
  516. 'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
  517. );
  518. begin
  519. stringtypname:=typname[string_typ];
  520. end;
  521. function tstringdef.size : longint;
  522. begin
  523. size:=savesize;
  524. end;
  525. procedure tstringdef.write;
  526. begin
  527. tdef.write;
  528. if string_typ=st_shortstring then
  529. writebyte(len)
  530. else
  531. writelong(len);
  532. case string_typ of
  533. st_shortstring : current_ppu^.writeentry(ibshortstringdef);
  534. st_longstring : current_ppu^.writeentry(iblongstringdef);
  535. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  536. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  537. end;
  538. end;
  539. {$ifdef GDB}
  540. function tstringdef.stabstring : pchar;
  541. var
  542. bytest,charst,longst : string;
  543. begin
  544. case string_typ of
  545. st_shortstring:
  546. begin
  547. charst := typeglobalnumber('char');
  548. { this is what I found in stabs.texinfo but
  549. gdb 4.12 for go32 doesn't understand that !! }
  550. {$IfDef GDBknowsstrings}
  551. stabstring := strpnew('n'+charst+';'+tostr(len));
  552. {$else}
  553. bytest := typeglobalnumber('byte');
  554. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  555. +',0,8;st:ar'+bytest
  556. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  557. {$EndIf}
  558. end;
  559. st_longstring:
  560. begin
  561. charst := typeglobalnumber('char');
  562. { this is what I found in stabs.texinfo but
  563. gdb 4.12 for go32 doesn't understand that !! }
  564. {$IfDef GDBknowsstrings}
  565. stabstring := strpnew('n'+charst+';'+tostr(len));
  566. {$else}
  567. bytest := typeglobalnumber('byte');
  568. longst := typeglobalnumber('longint');
  569. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  570. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  571. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  572. {$EndIf}
  573. end;
  574. st_ansistring:
  575. begin
  576. { an ansi string looks like a pchar easy !! }
  577. stabstring:=strpnew('*'+typeglobalnumber('char'));
  578. end;
  579. st_widestring:
  580. begin
  581. { an ansi string looks like a pchar easy !! }
  582. stabstring:=strpnew('*'+typeglobalnumber('char'));
  583. end;
  584. end;
  585. end;
  586. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  587. begin
  588. inherited concatstabto(asmlist);
  589. end;
  590. {$endif GDB}
  591. function tstringdef.needs_inittable : boolean;
  592. begin
  593. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  594. end;
  595. function tstringdef.gettypename : string;
  596. const
  597. names : array[tstringtype] of string[20] = ('',
  598. 'ShortString','LongString','AnsiString','WideString');
  599. begin
  600. gettypename:=names[string_typ];
  601. end;
  602. procedure tstringdef.write_rtti_data;
  603. begin
  604. case string_typ of
  605. st_ansistring:
  606. begin
  607. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  608. write_rtti_name;
  609. end;
  610. st_widestring:
  611. begin
  612. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  613. write_rtti_name;
  614. end;
  615. st_longstring:
  616. begin
  617. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  618. write_rtti_name;
  619. end;
  620. st_shortstring:
  621. begin
  622. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  623. write_rtti_name;
  624. rttilist^.concat(new(pai_const,init_8bit(len)));
  625. end;
  626. end;
  627. end;
  628. function tstringdef.is_publishable : boolean;
  629. begin
  630. is_publishable:=true;
  631. end;
  632. {****************************************************************************
  633. TENUMDEF
  634. ****************************************************************************}
  635. constructor tenumdef.init;
  636. begin
  637. tdef.init;
  638. deftype:=enumdef;
  639. minval:=0;
  640. maxval:=0;
  641. calcsavesize;
  642. has_jumps:=false;
  643. basedef:=nil;
  644. rangenr:=0;
  645. firstenum:=nil;
  646. correct_owner_symtable;
  647. end;
  648. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  649. begin
  650. tdef.init;
  651. deftype:=enumdef;
  652. minval:=_min;
  653. maxval:=_max;
  654. basedef:=_basedef;
  655. calcsavesize;
  656. has_jumps:=false;
  657. rangenr:=0;
  658. firstenum:=basedef^.firstenum;
  659. while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
  660. firstenum:=firstenum^.nextenum;
  661. correct_owner_symtable;
  662. end;
  663. constructor tenumdef.load;
  664. begin
  665. tdef.load;
  666. deftype:=enumdef;
  667. basedef:=penumdef(readdefref);
  668. minval:=readlong;
  669. maxval:=readlong;
  670. savesize:=readlong;
  671. has_jumps:=false;
  672. firstenum:=Nil;
  673. end;
  674. procedure tenumdef.calcsavesize;
  675. begin
  676. if (aktpackenum=4) or (min<0) or (max>65535) then
  677. savesize:=4
  678. else
  679. if (aktpackenum=2) or (min<0) or (max>255) then
  680. savesize:=2
  681. else
  682. savesize:=1;
  683. end;
  684. procedure tenumdef.setmax(_max:longint);
  685. begin
  686. maxval:=_max;
  687. calcsavesize;
  688. end;
  689. procedure tenumdef.setmin(_min:longint);
  690. begin
  691. minval:=_min;
  692. calcsavesize;
  693. end;
  694. function tenumdef.min:longint;
  695. begin
  696. min:=minval;
  697. end;
  698. function tenumdef.max:longint;
  699. begin
  700. max:=maxval;
  701. end;
  702. procedure tenumdef.deref;
  703. begin
  704. inherited deref;
  705. resolvedef(pdef(basedef));
  706. end;
  707. destructor tenumdef.done;
  708. begin
  709. inherited done;
  710. end;
  711. procedure tenumdef.write;
  712. begin
  713. tdef.write;
  714. writedefref(basedef);
  715. writelong(min);
  716. writelong(max);
  717. writelong(savesize);
  718. current_ppu^.writeentry(ibenumdef);
  719. end;
  720. function tenumdef.getrangecheckstring : string;
  721. begin
  722. if (cs_create_smart in aktmoduleswitches) then
  723. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  724. else
  725. getrangecheckstring:='R_'+tostr(rangenr);
  726. end;
  727. procedure tenumdef.genrangecheck;
  728. begin
  729. if rangenr=0 then
  730. begin
  731. { generate two constant for bounds }
  732. getlabelnr(rangenr);
  733. if (cs_create_smart in aktmoduleswitches) then
  734. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  735. else
  736. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  737. datasegment^.concat(new(pai_const,init_32bit(min)));
  738. datasegment^.concat(new(pai_const,init_32bit(max)));
  739. end;
  740. end;
  741. {$ifdef GDB}
  742. function tenumdef.stabstring : pchar;
  743. var st,st2 : pchar;
  744. p : penumsym;
  745. s : string;
  746. memsize : word;
  747. begin
  748. memsize := memsizeinc;
  749. getmem(st,memsize);
  750. strpcopy(st,'e');
  751. p := firstenum;
  752. while assigned(p) do
  753. begin
  754. s :=p^.name+':'+tostr(p^.value)+',';
  755. { place for the ending ';' also }
  756. if (strlen(st)+length(s)+1<memsize) then
  757. strpcopy(strend(st),s)
  758. else
  759. begin
  760. getmem(st2,memsize+memsizeinc);
  761. strcopy(st2,st);
  762. freemem(st,memsize);
  763. st := st2;
  764. memsize := memsize+memsizeinc;
  765. strpcopy(strend(st),s);
  766. end;
  767. p := p^.nextenum;
  768. end;
  769. strpcopy(strend(st),';');
  770. stabstring := strnew(st);
  771. freemem(st,memsize);
  772. end;
  773. {$endif GDB}
  774. procedure tenumdef.write_child_rtti_data;
  775. begin
  776. if assigned(basedef) then
  777. basedef^.get_rtti_label;
  778. end;
  779. procedure tenumdef.write_rtti_data;
  780. var
  781. hp : penumsym;
  782. begin
  783. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  784. write_rtti_name;
  785. case savesize of
  786. 1:
  787. rttilist^.concat(new(pai_const,init_8bit(otUByte)));
  788. 2:
  789. rttilist^.concat(new(pai_const,init_8bit(otUWord)));
  790. 4:
  791. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  792. end;
  793. rttilist^.concat(new(pai_const,init_32bit(min)));
  794. rttilist^.concat(new(pai_const,init_32bit(max)));
  795. if assigned(basedef) then
  796. rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
  797. else
  798. rttilist^.concat(new(pai_const,init_32bit(0)));
  799. hp:=firstenum;
  800. while assigned(hp) do
  801. begin
  802. rttilist^.concat(new(pai_const,init_8bit(length(hp^.name))));
  803. rttilist^.concat(new(pai_string,init(globals.lower(hp^.name))));
  804. hp:=hp^.nextenum;
  805. end;
  806. rttilist^.concat(new(pai_const,init_8bit(0)));
  807. end;
  808. function tenumdef.is_publishable : boolean;
  809. begin
  810. is_publishable:=true;
  811. end;
  812. function tenumdef.gettypename : string;
  813. begin
  814. gettypename:='<enumeration type>';
  815. end;
  816. {****************************************************************************
  817. TORDDEF
  818. ****************************************************************************}
  819. constructor torddef.init(t : tbasetype;v,b : longint);
  820. begin
  821. inherited init;
  822. deftype:=orddef;
  823. low:=v;
  824. high:=b;
  825. typ:=t;
  826. rangenr:=0;
  827. setsize;
  828. end;
  829. constructor torddef.load;
  830. begin
  831. inherited load;
  832. deftype:=orddef;
  833. typ:=tbasetype(readbyte);
  834. low:=readlong;
  835. high:=readlong;
  836. rangenr:=0;
  837. setsize;
  838. end;
  839. procedure torddef.setsize;
  840. begin
  841. if typ=uauto then
  842. begin
  843. { generate a unsigned range if high<0 and low>=0 }
  844. if (low>=0) and (high<0) then
  845. begin
  846. savesize:=4;
  847. typ:=u32bit;
  848. end
  849. else if (low>=0) and (high<=255) then
  850. begin
  851. savesize:=1;
  852. typ:=u8bit;
  853. end
  854. else if (low>=-128) and (high<=127) then
  855. begin
  856. savesize:=1;
  857. typ:=s8bit;
  858. end
  859. else if (low>=0) and (high<=65536) then
  860. begin
  861. savesize:=2;
  862. typ:=u16bit;
  863. end
  864. else if (low>=-32768) and (high<=32767) then
  865. begin
  866. savesize:=2;
  867. typ:=s16bit;
  868. end
  869. else
  870. begin
  871. savesize:=4;
  872. typ:=s32bit;
  873. end;
  874. end
  875. else
  876. begin
  877. case typ of
  878. u8bit,s8bit,
  879. uchar,bool8bit:
  880. savesize:=1;
  881. u16bit,s16bit,
  882. bool16bit,uwidechar:
  883. savesize:=2;
  884. s32bit,u32bit,
  885. bool32bit:
  886. savesize:=4;
  887. u64bit,s64bit:
  888. savesize:=8;
  889. else
  890. savesize:=0;
  891. end;
  892. end;
  893. { there are no entrys for range checking }
  894. rangenr:=0;
  895. end;
  896. function torddef.getrangecheckstring : string;
  897. begin
  898. if (cs_create_smart in aktmoduleswitches) then
  899. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  900. else
  901. getrangecheckstring:='R_'+tostr(rangenr);
  902. end;
  903. procedure torddef.genrangecheck;
  904. var
  905. rangechecksize : longint;
  906. begin
  907. if rangenr=0 then
  908. begin
  909. if low<=high then
  910. rangechecksize:=8
  911. else
  912. rangechecksize:=16;
  913. { generate two constant for bounds }
  914. getlabelnr(rangenr);
  915. if (cs_create_smart in aktmoduleswitches) then
  916. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,rangechecksize)))
  917. else
  918. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,rangechecksize)));
  919. if low<=high then
  920. begin
  921. datasegment^.concat(new(pai_const,init_32bit(low)));
  922. datasegment^.concat(new(pai_const,init_32bit(high)));
  923. end
  924. { for u32bit we need two bounds }
  925. else
  926. begin
  927. datasegment^.concat(new(pai_const,init_32bit(low)));
  928. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  929. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  930. datasegment^.concat(new(pai_const,init_32bit(high)));
  931. end;
  932. end;
  933. end;
  934. procedure torddef.write;
  935. begin
  936. tdef.write;
  937. writebyte(byte(typ));
  938. writelong(low);
  939. writelong(high);
  940. current_ppu^.writeentry(iborddef);
  941. end;
  942. {$ifdef GDB}
  943. function torddef.stabstring : pchar;
  944. begin
  945. case typ of
  946. uvoid : stabstring := strpnew(numberstring+';');
  947. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  948. {$ifdef Use_integer_types_for_boolean}
  949. bool8bit,
  950. bool16bit,
  951. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  952. {$else : not Use_integer_types_for_boolean}
  953. bool8bit : stabstring := strpnew('-21;');
  954. bool16bit : stabstring := strpnew('-22;');
  955. bool32bit : stabstring := strpnew('-23;');
  956. u64bit : stabstring := strpnew('-32;');
  957. s64bit : stabstring := strpnew('-31;');
  958. {$endif not Use_integer_types_for_boolean}
  959. { u32bit : stabstring := strpnew('r'+
  960. s32bitdef^.numberstring+';0;-1;'); }
  961. else
  962. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  963. end;
  964. end;
  965. {$endif GDB}
  966. procedure torddef.write_rtti_data;
  967. const
  968. trans : array[uchar..bool8bit] of byte =
  969. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  970. begin
  971. case typ of
  972. bool8bit:
  973. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  974. uchar:
  975. rttilist^.concat(new(pai_const,init_8bit(tkWChar)));
  976. uwidechar:
  977. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  978. else
  979. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  980. end;
  981. write_rtti_name;
  982. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  983. rttilist^.concat(new(pai_const,init_32bit(low)));
  984. rttilist^.concat(new(pai_const,init_32bit(high)));
  985. end;
  986. function torddef.is_publishable : boolean;
  987. begin
  988. is_publishable:=typ in [uchar..bool8bit];
  989. end;
  990. function torddef.gettypename : string;
  991. const
  992. names : array[tbasetype] of string[20] = ('<unknown type>',
  993. 'untyped','Char','Byte','Word','DWord','ShortInt',
  994. 'SmallInt','LongInt','Boolean','WordBool',
  995. 'LongBool','QWord','Int64','WideChar');
  996. begin
  997. gettypename:=names[typ];
  998. end;
  999. {****************************************************************************
  1000. TFLOATDEF
  1001. ****************************************************************************}
  1002. constructor tfloatdef.init(t : tfloattype);
  1003. begin
  1004. inherited init;
  1005. deftype:=floatdef;
  1006. typ:=t;
  1007. setsize;
  1008. end;
  1009. constructor tfloatdef.load;
  1010. begin
  1011. inherited load;
  1012. deftype:=floatdef;
  1013. typ:=tfloattype(readbyte);
  1014. setsize;
  1015. end;
  1016. procedure tfloatdef.setsize;
  1017. begin
  1018. case typ of
  1019. f16bit : savesize:=2;
  1020. f32bit,
  1021. s32real : savesize:=4;
  1022. s64real : savesize:=8;
  1023. s80real : savesize:=extended_size;
  1024. s64comp : savesize:=8;
  1025. else
  1026. savesize:=0;
  1027. end;
  1028. end;
  1029. procedure tfloatdef.write;
  1030. begin
  1031. inherited write;
  1032. writebyte(byte(typ));
  1033. current_ppu^.writeentry(ibfloatdef);
  1034. end;
  1035. {$ifdef GDB}
  1036. function tfloatdef.stabstring : pchar;
  1037. begin
  1038. case typ of
  1039. s32real,
  1040. s64real : stabstring := strpnew('r'+
  1041. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  1042. { for fixed real use longint instead to be able to }
  1043. { debug something at least }
  1044. f32bit:
  1045. stabstring := s32bitdef^.stabstring;
  1046. f16bit:
  1047. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  1048. tostr($ffff)+';');
  1049. { found this solution in stabsread.c from GDB v4.16 }
  1050. s64comp : stabstring := strpnew('r'+
  1051. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  1052. {$ifdef i386}
  1053. { under dos at least you must give a size of twelve instead of 10 !! }
  1054. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1055. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  1056. {$endif i386}
  1057. else
  1058. internalerror(10005);
  1059. end;
  1060. end;
  1061. {$endif GDB}
  1062. procedure tfloatdef.write_rtti_data;
  1063. const
  1064. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  1065. translate : array[tfloattype] of byte =
  1066. (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
  1067. begin
  1068. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  1069. write_rtti_name;
  1070. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  1071. end;
  1072. function tfloatdef.is_publishable : boolean;
  1073. begin
  1074. is_publishable:=true;
  1075. end;
  1076. function tfloatdef.gettypename : string;
  1077. const
  1078. names : array[tfloattype] of string[20] = (
  1079. 'Single','Double','Extended','Comp','Fixed','Fixed16');
  1080. begin
  1081. gettypename:=names[typ];
  1082. end;
  1083. {****************************************************************************
  1084. TFILEDEF
  1085. ****************************************************************************}
  1086. constructor tfiledef.inittext;
  1087. begin
  1088. inherited init;
  1089. deftype:=filedef;
  1090. filetyp:=ft_text;
  1091. typedfiletype.reset;
  1092. setsize;
  1093. end;
  1094. constructor tfiledef.inituntyped;
  1095. begin
  1096. inherited init;
  1097. deftype:=filedef;
  1098. filetyp:=ft_untyped;
  1099. typedfiletype.reset;
  1100. setsize;
  1101. end;
  1102. constructor tfiledef.inittyped(const tt : ttype);
  1103. begin
  1104. inherited init;
  1105. deftype:=filedef;
  1106. filetyp:=ft_typed;
  1107. typedfiletype:=tt;
  1108. setsize;
  1109. end;
  1110. constructor tfiledef.inittypeddef(p : pdef);
  1111. begin
  1112. inherited init;
  1113. deftype:=filedef;
  1114. filetyp:=ft_typed;
  1115. typedfiletype.setdef(p);
  1116. setsize;
  1117. end;
  1118. constructor tfiledef.load;
  1119. begin
  1120. inherited load;
  1121. deftype:=filedef;
  1122. filetyp:=tfiletyp(readbyte);
  1123. if filetyp=ft_typed then
  1124. typedfiletype.load
  1125. else
  1126. typedfiletype.reset;
  1127. setsize;
  1128. end;
  1129. procedure tfiledef.deref;
  1130. begin
  1131. inherited deref;
  1132. if filetyp=ft_typed then
  1133. typedfiletype.resolve;
  1134. end;
  1135. procedure tfiledef.setsize;
  1136. begin
  1137. case filetyp of
  1138. ft_text :
  1139. savesize:=572;
  1140. ft_typed,
  1141. ft_untyped :
  1142. savesize:=316;
  1143. end;
  1144. end;
  1145. procedure tfiledef.write;
  1146. begin
  1147. inherited write;
  1148. writebyte(byte(filetyp));
  1149. if filetyp=ft_typed then
  1150. typedfiletype.write;
  1151. current_ppu^.writeentry(ibfiledef);
  1152. end;
  1153. {$ifdef GDB}
  1154. function tfiledef.stabstring : pchar;
  1155. begin
  1156. {$IfDef GDBknowsfiles}
  1157. case filetyp of
  1158. ft_typed :
  1159. stabstring := strpnew('d'+typedfiletype.def^.numberstring{+';'});
  1160. ft_untyped :
  1161. stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  1162. ft_text :
  1163. stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  1164. end;
  1165. {$Else}
  1166. {based on
  1167. FileRec = Packed Record
  1168. Handle,
  1169. Mode,
  1170. RecSize : longint;
  1171. _private : array[1..32] of byte;
  1172. UserData : array[1..16] of byte;
  1173. name : array[0..255] of char;
  1174. End; }
  1175. { the buffer part is still missing !! (PM) }
  1176. { but the string could become too long !! }
  1177. stabstring := strpnew('s'+tostr(savesize)+
  1178. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1179. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1180. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1181. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1182. +',96,256;'+
  1183. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1184. +',352,128;'+
  1185. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1186. +',480,2048;;');
  1187. {$EndIf}
  1188. end;
  1189. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  1190. begin
  1191. { most file defs are unnamed !!! }
  1192. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1193. not is_def_stab_written then
  1194. begin
  1195. if assigned(typedfiletype.def) then forcestabto(asmlist,typedfiletype.def);
  1196. inherited concatstabto(asmlist);
  1197. end;
  1198. end;
  1199. {$endif GDB}
  1200. function tfiledef.gettypename : string;
  1201. begin
  1202. case filetyp of
  1203. ft_untyped:
  1204. gettypename:='File';
  1205. ft_typed:
  1206. gettypename:='File Of '+typedfiletype.def^.typename;
  1207. ft_text:
  1208. gettypename:='Text'
  1209. end;
  1210. end;
  1211. {****************************************************************************
  1212. TPOINTERDEF
  1213. ****************************************************************************}
  1214. constructor tpointerdef.init(const tt : ttype);
  1215. begin
  1216. tdef.init;
  1217. deftype:=pointerdef;
  1218. pointertype:=tt;
  1219. is_far:=false;
  1220. savesize:=target_os.size_of_pointer;
  1221. end;
  1222. constructor tpointerdef.initfar(const tt : ttype);
  1223. begin
  1224. tdef.init;
  1225. deftype:=pointerdef;
  1226. pointertype:=tt;
  1227. is_far:=true;
  1228. savesize:=target_os.size_of_pointer;
  1229. end;
  1230. constructor tpointerdef.initdef(p : pdef);
  1231. var
  1232. t : ttype;
  1233. begin
  1234. t.setdef(p);
  1235. tpointerdef.init(t);
  1236. end;
  1237. constructor tpointerdef.initfardef(p : pdef);
  1238. var
  1239. t : ttype;
  1240. begin
  1241. t.setdef(p);
  1242. tpointerdef.initfar(t);
  1243. end;
  1244. constructor tpointerdef.load;
  1245. begin
  1246. tdef.load;
  1247. deftype:=pointerdef;
  1248. pointertype.load;
  1249. is_far:=(readbyte<>0);
  1250. savesize:=target_os.size_of_pointer;
  1251. end;
  1252. destructor tpointerdef.done;
  1253. begin
  1254. if assigned(pointertype.def) and
  1255. (pointertype.def^.deftype=forwarddef) then
  1256. begin
  1257. dispose(pointertype.def,done);
  1258. pointertype.reset;
  1259. end;
  1260. inherited done;
  1261. end;
  1262. procedure tpointerdef.deref;
  1263. begin
  1264. inherited deref;
  1265. pointertype.resolve;
  1266. end;
  1267. procedure tpointerdef.write;
  1268. begin
  1269. inherited write;
  1270. pointertype.write;
  1271. writebyte(byte(is_far));
  1272. current_ppu^.writeentry(ibpointerdef);
  1273. end;
  1274. {$ifdef GDB}
  1275. function tpointerdef.stabstring : pchar;
  1276. begin
  1277. stabstring := strpnew('*'+pointertype.def^.numberstring);
  1278. end;
  1279. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1280. var st,nb : string;
  1281. sym_line_no : longint;
  1282. begin
  1283. if assigned(pointertype.def) and
  1284. (pointertype.def^.deftype=forwarddef) then
  1285. exit;
  1286. if ( (typesym=nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1287. not is_def_stab_written then
  1288. begin
  1289. if assigned(pointertype.def) then
  1290. if pointertype.def^.deftype in [recorddef,objectdef] then
  1291. begin
  1292. is_def_stab_written := true;
  1293. nb:=pointertype.def^.numberstring;
  1294. {to avoid infinite recursion in record with next-like fields }
  1295. is_def_stab_written := false;
  1296. if not pointertype.def^.is_def_stab_written then
  1297. begin
  1298. if assigned(pointertype.def^.typesym) then
  1299. begin
  1300. if assigned(typesym) then
  1301. begin
  1302. st := typesym^.name;
  1303. sym_line_no:=typesym^.fileinfo.line;
  1304. end
  1305. else
  1306. begin
  1307. st := ' ';
  1308. sym_line_no:=0;
  1309. end;
  1310. st := '"'+st+':t'+numberstring+'=*'+nb
  1311. +'=xs'+pointertype.def^.typesym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1312. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1313. end;
  1314. end else inherited concatstabto(asmlist);
  1315. is_def_stab_written := true;
  1316. end else
  1317. begin
  1318. { p =^p1; p1=^p problem }
  1319. is_def_stab_written := true;
  1320. forcestabto(asmlist,pointertype.def);
  1321. is_def_stab_written := false;
  1322. inherited concatstabto(asmlist);
  1323. end;
  1324. end;
  1325. end;
  1326. {$endif GDB}
  1327. function tpointerdef.gettypename : string;
  1328. begin
  1329. gettypename:='^'+pointertype.def^.typename;
  1330. end;
  1331. {****************************************************************************
  1332. TCLASSREFDEF
  1333. ****************************************************************************}
  1334. constructor tclassrefdef.init(def : pdef);
  1335. begin
  1336. inherited initdef(def);
  1337. deftype:=classrefdef;
  1338. end;
  1339. constructor tclassrefdef.load;
  1340. begin
  1341. { be careful, tclassdefref inherits from tpointerdef }
  1342. tdef.load;
  1343. deftype:=classrefdef;
  1344. pointertype.load;
  1345. is_far:=false;
  1346. savesize:=target_os.size_of_pointer;
  1347. end;
  1348. procedure tclassrefdef.write;
  1349. begin
  1350. { be careful, tclassdefref inherits from tpointerdef }
  1351. tdef.write;
  1352. pointertype.write;
  1353. current_ppu^.writeentry(ibclassrefdef);
  1354. end;
  1355. {$ifdef GDB}
  1356. function tclassrefdef.stabstring : pchar;
  1357. begin
  1358. stabstring:=strpnew(pvmtdef^.numberstring+';');
  1359. end;
  1360. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1361. begin
  1362. inherited concatstabto(asmlist);
  1363. end;
  1364. {$endif GDB}
  1365. function tclassrefdef.gettypename : string;
  1366. begin
  1367. gettypename:='Class Of '+pointertype.def^.typename;
  1368. end;
  1369. {***************************************************************************
  1370. TSETDEF
  1371. ***************************************************************************}
  1372. { For i386 smallsets work,
  1373. for m68k there are problems
  1374. can be test by compiling with -dusesmallset PM }
  1375. {$ifdef i386}
  1376. {$define usesmallset}
  1377. {$endif i386}
  1378. constructor tsetdef.init(s : pdef;high : longint);
  1379. begin
  1380. inherited init;
  1381. deftype:=setdef;
  1382. elementtype.setdef(s);
  1383. {$ifdef usesmallset}
  1384. { small sets only working for i386 PM }
  1385. if high<32 then
  1386. begin
  1387. settype:=smallset;
  1388. {$ifdef testvarsets}
  1389. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  1390. {$endif}
  1391. savesize:=Sizeof(longint)
  1392. {$ifdef testvarsets}
  1393. else {No, use $PACKSET VALUE for rounding}
  1394. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  1395. {$endif}
  1396. ;
  1397. end
  1398. else
  1399. {$endif usesmallset}
  1400. if high<256 then
  1401. begin
  1402. settype:=normset;
  1403. savesize:=32;
  1404. end
  1405. else
  1406. {$ifdef testvarsets}
  1407. if high<$10000 then
  1408. begin
  1409. settype:=varset;
  1410. savesize:=4*((high+31) div 32);
  1411. end
  1412. else
  1413. {$endif testvarsets}
  1414. Message(sym_e_ill_type_decl_set);
  1415. end;
  1416. constructor tsetdef.load;
  1417. begin
  1418. inherited load;
  1419. deftype:=setdef;
  1420. elementtype.load;
  1421. settype:=tsettype(readbyte);
  1422. case settype of
  1423. normset : savesize:=32;
  1424. varset : savesize:=readlong;
  1425. smallset : savesize:=Sizeof(longint);
  1426. end;
  1427. end;
  1428. destructor tsetdef.done;
  1429. begin
  1430. inherited done;
  1431. end;
  1432. procedure tsetdef.write;
  1433. begin
  1434. inherited write;
  1435. elementtype.write;
  1436. writebyte(byte(settype));
  1437. if settype=varset then
  1438. writelong(savesize);
  1439. current_ppu^.writeentry(ibsetdef);
  1440. end;
  1441. {$ifdef GDB}
  1442. function tsetdef.stabstring : pchar;
  1443. begin
  1444. { For small sets write a longint, which can at least be seen
  1445. in the current GDB's (PFV)
  1446. this is obsolete with GDBPAS !!
  1447. and anyhow creates problems with version 4.18!! PM
  1448. if settype=smallset then
  1449. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
  1450. else }
  1451. stabstring := strpnew('S'+elementtype.def^.numberstring);
  1452. end;
  1453. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1454. begin
  1455. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1456. not is_def_stab_written then
  1457. begin
  1458. if assigned(elementtype.def) then
  1459. forcestabto(asmlist,elementtype.def);
  1460. inherited concatstabto(asmlist);
  1461. end;
  1462. end;
  1463. {$endif GDB}
  1464. procedure tsetdef.deref;
  1465. begin
  1466. inherited deref;
  1467. elementtype.resolve;
  1468. end;
  1469. procedure tsetdef.write_rtti_data;
  1470. begin
  1471. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  1472. write_rtti_name;
  1473. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1474. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1475. end;
  1476. procedure tsetdef.write_child_rtti_data;
  1477. begin
  1478. elementtype.def^.get_rtti_label;
  1479. end;
  1480. function tsetdef.is_publishable : boolean;
  1481. begin
  1482. is_publishable:=settype=smallset;
  1483. end;
  1484. function tsetdef.gettypename : string;
  1485. begin
  1486. gettypename:='Set Of '+elementtype.def^.typename;
  1487. end;
  1488. {***************************************************************************
  1489. TFORMALDEF
  1490. ***************************************************************************}
  1491. constructor tformaldef.init;
  1492. var
  1493. stregdef : boolean;
  1494. begin
  1495. stregdef:=registerdef;
  1496. registerdef:=false;
  1497. inherited init;
  1498. deftype:=formaldef;
  1499. registerdef:=stregdef;
  1500. { formaldef must be registered at unit level !! }
  1501. if registerdef and assigned(current_module) then
  1502. if assigned(current_module^.localsymtable) then
  1503. psymtable(current_module^.localsymtable)^.registerdef(@self)
  1504. else if assigned(current_module^.globalsymtable) then
  1505. psymtable(current_module^.globalsymtable)^.registerdef(@self);
  1506. savesize:=target_os.size_of_pointer;
  1507. end;
  1508. constructor tformaldef.load;
  1509. begin
  1510. inherited load;
  1511. deftype:=formaldef;
  1512. savesize:=target_os.size_of_pointer;
  1513. end;
  1514. procedure tformaldef.write;
  1515. begin
  1516. inherited write;
  1517. current_ppu^.writeentry(ibformaldef);
  1518. end;
  1519. {$ifdef GDB}
  1520. function tformaldef.stabstring : pchar;
  1521. begin
  1522. stabstring := strpnew('formal'+numberstring+';');
  1523. end;
  1524. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1525. begin
  1526. { formaldef can't be stab'ed !}
  1527. end;
  1528. {$endif GDB}
  1529. function tformaldef.gettypename : string;
  1530. begin
  1531. gettypename:='Var';
  1532. end;
  1533. {***************************************************************************
  1534. TARRAYDEF
  1535. ***************************************************************************}
  1536. constructor tarraydef.init(l,h : longint;rd : pdef);
  1537. begin
  1538. inherited init;
  1539. deftype:=arraydef;
  1540. lowrange:=l;
  1541. highrange:=h;
  1542. rangetype.setdef(rd);
  1543. elementtype.reset;
  1544. IsVariant:=false;
  1545. IsConstructor:=false;
  1546. IsArrayOfConst:=false;
  1547. rangenr:=0;
  1548. end;
  1549. constructor tarraydef.load;
  1550. begin
  1551. inherited load;
  1552. deftype:=arraydef;
  1553. { the addresses are calculated later }
  1554. elementtype.load;
  1555. rangetype.load;
  1556. lowrange:=readlong;
  1557. highrange:=readlong;
  1558. IsArrayOfConst:=boolean(readbyte);
  1559. IsVariant:=false;
  1560. IsConstructor:=false;
  1561. rangenr:=0;
  1562. end;
  1563. function tarraydef.getrangecheckstring : string;
  1564. begin
  1565. if (cs_create_smart in aktmoduleswitches) then
  1566. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1567. else
  1568. getrangecheckstring:='R_'+tostr(rangenr);
  1569. end;
  1570. procedure tarraydef.genrangecheck;
  1571. begin
  1572. if rangenr=0 then
  1573. begin
  1574. { generates the data for range checking }
  1575. getlabelnr(rangenr);
  1576. if (cs_create_smart in aktmoduleswitches) then
  1577. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  1578. else
  1579. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  1580. if lowrange<=highrange then
  1581. begin
  1582. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1583. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1584. end
  1585. { for big arrays we need two bounds }
  1586. else
  1587. begin
  1588. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1589. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  1590. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  1591. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1592. end;
  1593. end;
  1594. end;
  1595. procedure tarraydef.deref;
  1596. begin
  1597. inherited deref;
  1598. elementtype.resolve;
  1599. rangetype.resolve;
  1600. end;
  1601. procedure tarraydef.write;
  1602. begin
  1603. inherited write;
  1604. elementtype.write;
  1605. rangetype.write;
  1606. writelong(lowrange);
  1607. writelong(highrange);
  1608. writebyte(byte(IsArrayOfConst));
  1609. current_ppu^.writeentry(ibarraydef);
  1610. end;
  1611. {$ifdef GDB}
  1612. function tarraydef.stabstring : pchar;
  1613. begin
  1614. stabstring := strpnew('ar'+rangetype.def^.numberstring+';'
  1615. +tostr(lowrange)+';'+tostr(highrange)+';'+elementtype.def^.numberstring);
  1616. end;
  1617. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1618. begin
  1619. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1620. and not is_def_stab_written then
  1621. begin
  1622. {when array are inserted they have no definition yet !!}
  1623. if assigned(elementtype.def) then
  1624. inherited concatstabto(asmlist);
  1625. end;
  1626. end;
  1627. {$endif GDB}
  1628. function tarraydef.elesize : longint;
  1629. begin
  1630. if isconstructor or is_open_array(@self) then
  1631. begin
  1632. { strings are stored by address only }
  1633. case elementtype.def^.deftype of
  1634. stringdef :
  1635. elesize:=4;
  1636. else
  1637. elesize:=elementtype.def^.size;
  1638. end;
  1639. end
  1640. else
  1641. elesize:=elementtype.def^.size;
  1642. end;
  1643. function tarraydef.size : longint;
  1644. begin
  1645. {Tarraydef.size may never be called for an open array!}
  1646. if highrange<lowrange then
  1647. internalerror(99080501);
  1648. If (elesize>0) and
  1649. (
  1650. (highrange-lowrange = $7fffffff) or
  1651. { () are needed around elesize-1 to avoid a possible
  1652. integer overflow for elesize=1 !! PM }
  1653. (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
  1654. ) Then
  1655. Begin
  1656. Message(sym_e_segment_too_large);
  1657. size := 4
  1658. End
  1659. Else size:=(highrange-lowrange+1)*elesize;
  1660. end;
  1661. function tarraydef.alignment : longint;
  1662. begin
  1663. { alignment is the size of the elements }
  1664. alignment:=elesize;
  1665. end;
  1666. function tarraydef.needs_inittable : boolean;
  1667. begin
  1668. needs_inittable:=elementtype.def^.needs_inittable;
  1669. end;
  1670. procedure tarraydef.write_child_rtti_data;
  1671. begin
  1672. elementtype.def^.get_rtti_label;
  1673. end;
  1674. procedure tarraydef.write_rtti_data;
  1675. begin
  1676. rttilist^.concat(new(pai_const,init_8bit(tkarray)));
  1677. write_rtti_name;
  1678. { size of elements }
  1679. rttilist^.concat(new(pai_const,init_32bit(elesize)));
  1680. { count of elements }
  1681. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1682. { element type }
  1683. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1684. end;
  1685. function tarraydef.gettypename : string;
  1686. begin
  1687. if isarrayofconst or isConstructor then
  1688. begin
  1689. if isvariant then
  1690. gettypename:='Array Of Const'
  1691. else
  1692. gettypename:='Array Of '+elementtype.def^.typename;
  1693. end
  1694. else if is_open_array(@self) then
  1695. gettypename:='Array Of '+elementtype.def^.typename
  1696. else
  1697. begin
  1698. if rangetype.def^.deftype=enumdef then
  1699. gettypename:='Array['+rangetype.def^.typename+'] Of '+elementtype.def^.typename
  1700. else
  1701. gettypename:='Array['+tostr(lowrange)+'..'+
  1702. tostr(highrange)+'] Of '+elementtype.def^.typename
  1703. end;
  1704. end;
  1705. {***************************************************************************
  1706. trecorddef
  1707. ***************************************************************************}
  1708. constructor trecorddef.init(p : psymtable);
  1709. begin
  1710. inherited init;
  1711. deftype:=recorddef;
  1712. symtable:=p;
  1713. symtable^.defowner := @self;
  1714. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  1715. end;
  1716. constructor trecorddef.load;
  1717. var
  1718. oldread_member : boolean;
  1719. begin
  1720. inherited load;
  1721. deftype:=recorddef;
  1722. savesize:=readlong;
  1723. oldread_member:=read_member;
  1724. read_member:=true;
  1725. symtable:=new(psymtable,loadas(recordsymtable));
  1726. read_member:=oldread_member;
  1727. symtable^.defowner := @self;
  1728. end;
  1729. destructor trecorddef.done;
  1730. begin
  1731. if assigned(symtable) then
  1732. dispose(symtable,done);
  1733. inherited done;
  1734. end;
  1735. var
  1736. binittable : boolean;
  1737. procedure check_rec_inittable(s : pnamedindexobject);
  1738. begin
  1739. if (not binittable) and
  1740. (psym(s)^.typ=varsym) and
  1741. assigned(pvarsym(s)^.vartype.def) then
  1742. begin
  1743. if ((pvarsym(s)^.vartype.def^.deftype<>objectdef) or
  1744. not(pobjectdef(pvarsym(s)^.vartype.def)^.is_class)) then
  1745. binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
  1746. end;
  1747. end;
  1748. function trecorddef.needs_inittable : boolean;
  1749. var
  1750. oldb : boolean;
  1751. begin
  1752. { there are recursive calls to needs_rtti possible, }
  1753. { so we have to change to old value how else should }
  1754. { we do that ? check_rec_rtti can't be a nested }
  1755. { procedure of needs_rtti ! }
  1756. oldb:=binittable;
  1757. binittable:=false;
  1758. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  1759. needs_inittable:=binittable;
  1760. binittable:=oldb;
  1761. end;
  1762. procedure trecorddef.deref;
  1763. var
  1764. oldrecsyms : psymtable;
  1765. begin
  1766. inherited deref;
  1767. oldrecsyms:=aktrecordsymtable;
  1768. aktrecordsymtable:=symtable;
  1769. { now dereference the definitions }
  1770. symtable^.deref;
  1771. aktrecordsymtable:=oldrecsyms;
  1772. end;
  1773. procedure trecorddef.write;
  1774. var
  1775. oldread_member : boolean;
  1776. begin
  1777. oldread_member:=read_member;
  1778. read_member:=true;
  1779. inherited write;
  1780. writelong(savesize);
  1781. current_ppu^.writeentry(ibrecorddef);
  1782. self.symtable^.writeas;
  1783. read_member:=oldread_member;
  1784. end;
  1785. function trecorddef.size:longint;
  1786. begin
  1787. size:=symtable^.datasize;
  1788. end;
  1789. function trecorddef.alignment:longint;
  1790. var
  1791. l : longint;
  1792. hp : pvarsym;
  1793. begin
  1794. { also check the first symbol for it's size, because a
  1795. packed record has dataalignment of 1, but the first
  1796. sym could be a longint which should be aligned on 4 bytes,
  1797. this is compatible with C record packing (PFV) }
  1798. hp:=pvarsym(symtable^.symindex^.first);
  1799. if assigned(hp) then
  1800. begin
  1801. l:=hp^.vartype.def^.size;
  1802. if l>symtable^.dataalignment then
  1803. begin
  1804. if l>=4 then
  1805. alignment:=4
  1806. else
  1807. if l>=2 then
  1808. alignment:=2
  1809. else
  1810. alignment:=1;
  1811. end
  1812. else
  1813. alignment:=symtable^.dataalignment;
  1814. end
  1815. else
  1816. alignment:=symtable^.dataalignment;
  1817. end;
  1818. {$ifdef GDB}
  1819. Const StabRecString : pchar = Nil;
  1820. StabRecSize : longint = 0;
  1821. RecOffset : Longint = 0;
  1822. procedure addname(p : pnamedindexobject);
  1823. var
  1824. news, newrec : pchar;
  1825. spec : string[3];
  1826. size : longint;
  1827. begin
  1828. { static variables from objects are like global objects }
  1829. if (sp_static in psym(p)^.symoptions) then
  1830. exit;
  1831. If psym(p)^.typ = varsym then
  1832. begin
  1833. if (sp_protected in psym(p)^.symoptions) then
  1834. spec:='/1'
  1835. else if (sp_private in psym(p)^.symoptions) then
  1836. spec:='/0'
  1837. else
  1838. spec:='';
  1839. { class fields are pointers PM }
  1840. if not assigned(pvarsym(p)^.vartype.def) then
  1841. writeln(pvarsym(p)^.name);
  1842. if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
  1843. pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
  1844. spec:=spec+'*';
  1845. size:=pvarsym(p)^.vartype.def^.size;
  1846. { open arrays made overflows !! }
  1847. if size>$fffffff then
  1848. size:=$fffffff;
  1849. newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.vartype.def^.numberstring
  1850. +','+tostr(pvarsym(p)^.address*8)+','
  1851. +tostr(size*8)+';');
  1852. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1853. begin
  1854. getmem(news,stabrecsize+memsizeinc);
  1855. strcopy(news,stabrecstring);
  1856. freemem(stabrecstring,stabrecsize);
  1857. stabrecsize:=stabrecsize+memsizeinc;
  1858. stabrecstring:=news;
  1859. end;
  1860. strcat(StabRecstring,newrec);
  1861. strdispose(newrec);
  1862. {This should be used for case !!}
  1863. RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;
  1864. end;
  1865. end;
  1866. function trecorddef.stabstring : pchar;
  1867. Var oldrec : pchar;
  1868. oldsize : longint;
  1869. begin
  1870. oldrec := stabrecstring;
  1871. oldsize:=stabrecsize;
  1872. GetMem(stabrecstring,memsizeinc);
  1873. stabrecsize:=memsizeinc;
  1874. strpcopy(stabRecString,'s'+tostr(size));
  1875. RecOffset := 0;
  1876. symtable^.foreach({$ifndef TP}@{$endif}addname);
  1877. { FPC doesn't want to convert a char to a pchar}
  1878. { is this a bug ? }
  1879. strpcopy(strend(StabRecString),';');
  1880. stabstring := strnew(StabRecString);
  1881. Freemem(stabrecstring,stabrecsize);
  1882. stabrecstring := oldrec;
  1883. stabrecsize:=oldsize;
  1884. end;
  1885. procedure trecorddef.concatstabto(asmlist : paasmoutput);
  1886. begin
  1887. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1888. (not is_def_stab_written) then
  1889. inherited concatstabto(asmlist);
  1890. end;
  1891. {$endif GDB}
  1892. var
  1893. count : longint;
  1894. procedure count_inittable_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1895. begin
  1896. if ((psym(sym)^.typ=varsym) and
  1897. pvarsym(sym)^.vartype.def^.needs_inittable)
  1898. and ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1899. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1900. inc(count);
  1901. end;
  1902. procedure count_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1903. begin
  1904. inc(count);
  1905. end;
  1906. procedure write_field_inittable(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1907. begin
  1908. if ((psym(sym)^.typ=varsym) and
  1909. pvarsym(sym)^.vartype.def^.needs_inittable) and
  1910. ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1911. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1912. begin
  1913. rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.vartype.def^.get_inittable_label)));
  1914. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1915. end;
  1916. end;
  1917. procedure write_field_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1918. begin
  1919. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  1920. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1921. end;
  1922. procedure generate_child_inittable(sym:pnamedindexobject);{$ifndef fpc}far;{$endif}
  1923. begin
  1924. if (psym(sym)^.typ=varsym) and
  1925. pvarsym(sym)^.vartype.def^.needs_inittable then
  1926. { force inittable generation }
  1927. pvarsym(sym)^.vartype.def^.get_inittable_label;
  1928. end;
  1929. procedure generate_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1930. begin
  1931. pvarsym(sym)^.vartype.def^.get_rtti_label;
  1932. end;
  1933. procedure trecorddef.write_child_rtti_data;
  1934. begin
  1935. symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
  1936. end;
  1937. procedure trecorddef.write_child_init_data;
  1938. begin
  1939. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  1940. end;
  1941. procedure trecorddef.write_rtti_data;
  1942. begin
  1943. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1944. write_rtti_name;
  1945. rttilist^.concat(new(pai_const,init_32bit(size)));
  1946. count:=0;
  1947. symtable^.foreach({$ifndef TP}@{$endif}count_fields);
  1948. rttilist^.concat(new(pai_const,init_32bit(count)));
  1949. symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
  1950. end;
  1951. procedure trecorddef.write_init_data;
  1952. begin
  1953. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1954. write_rtti_name;
  1955. rttilist^.concat(new(pai_const,init_32bit(size)));
  1956. count:=0;
  1957. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  1958. rttilist^.concat(new(pai_const,init_32bit(count)));
  1959. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  1960. end;
  1961. function trecorddef.gettypename : string;
  1962. begin
  1963. gettypename:='<record type>'
  1964. end;
  1965. {***************************************************************************
  1966. TABSTRACTPROCDEF
  1967. ***************************************************************************}
  1968. constructor tabstractprocdef.init;
  1969. begin
  1970. inherited init;
  1971. new(para,init);
  1972. fpu_used:=0;
  1973. proctypeoption:=potype_none;
  1974. proccalloptions:=[];
  1975. procoptions:=[];
  1976. rettype.setdef(voiddef);
  1977. symtablelevel:=0;
  1978. savesize:=target_os.size_of_pointer;
  1979. end;
  1980. destructor tabstractprocdef.done;
  1981. begin
  1982. dispose(para,done);
  1983. inherited done;
  1984. end;
  1985. procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez);
  1986. var
  1987. hp : pparaitem;
  1988. begin
  1989. new(hp,init);
  1990. hp^.paratyp:=vsp;
  1991. hp^.paratype:=tt;
  1992. hp^.register:=R_NO;
  1993. para^.insert(hp);
  1994. end;
  1995. { all functions returning in FPU are
  1996. assume to use 2 FPU registers
  1997. until the function implementation
  1998. is processed PM }
  1999. procedure tabstractprocdef.test_if_fpu_result;
  2000. begin
  2001. if assigned(rettype.def) and is_fpu(rettype.def) then
  2002. fpu_used:=2;
  2003. end;
  2004. procedure tabstractprocdef.deref;
  2005. var
  2006. hp : pparaitem;
  2007. begin
  2008. inherited deref;
  2009. rettype.resolve;
  2010. hp:=pparaitem(para^.first);
  2011. while assigned(hp) do
  2012. begin
  2013. hp^.paratype.resolve;
  2014. hp:=pparaitem(hp^.next);
  2015. end;
  2016. end;
  2017. constructor tabstractprocdef.load;
  2018. var
  2019. hp : pparaitem;
  2020. count,i : word;
  2021. begin
  2022. inherited load;
  2023. new(para,init);
  2024. rettype.load;
  2025. fpu_used:=readbyte;
  2026. proctypeoption:=tproctypeoption(readlong);
  2027. readsmallset(proccalloptions);
  2028. readsmallset(procoptions);
  2029. count:=readword;
  2030. savesize:=target_os.size_of_pointer;
  2031. for i:=1 to count do
  2032. begin
  2033. new(hp,init);
  2034. hp^.paratyp:=tvarspez(readbyte);
  2035. { hp^.register:=tregister(readbyte); }
  2036. hp^.register:=R_NO;
  2037. hp^.paratype.load;
  2038. para^.concat(hp);
  2039. end;
  2040. end;
  2041. procedure tabstractprocdef.write;
  2042. var
  2043. hp : pparaitem;
  2044. begin
  2045. inherited write;
  2046. rettype.write;
  2047. current_ppu^.do_interface_crc:=false;
  2048. writebyte(fpu_used);
  2049. writelong(ord(proctypeoption));
  2050. writesmallset(proccalloptions);
  2051. writesmallset(procoptions);
  2052. writeword(para^.count);
  2053. hp:=pparaitem(para^.first);
  2054. while assigned(hp) do
  2055. begin
  2056. writebyte(byte(hp^.paratyp));
  2057. { writebyte(byte(hp^.register)); }
  2058. hp^.paratype.write;
  2059. hp:=pparaitem(hp^.next);
  2060. end;
  2061. end;
  2062. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2063. var
  2064. pdc : pparaitem;
  2065. l : longint;
  2066. begin
  2067. l:=0;
  2068. pdc:=pparaitem(para^.first);
  2069. while assigned(pdc) do
  2070. begin
  2071. case pdc^.paratyp of
  2072. vs_var : inc(l,target_os.size_of_pointer);
  2073. vs_value,
  2074. vs_const : if push_addr_param(pdc^.paratype.def) then
  2075. inc(l,target_os.size_of_pointer)
  2076. else
  2077. inc(l,pdc^.paratype.def^.size);
  2078. end;
  2079. l:=align(l,alignsize);
  2080. pdc:=pparaitem(pdc^.next);
  2081. end;
  2082. para_size:=l;
  2083. end;
  2084. function tabstractprocdef.demangled_paras : string;
  2085. var
  2086. s : string;
  2087. hp : pparaitem;
  2088. begin
  2089. s:='(';
  2090. hp:=pparaitem(para^.last);
  2091. while assigned(hp) do
  2092. begin
  2093. if assigned(hp^.paratype.def^.typesym) then
  2094. s:=s+hp^.paratype.def^.typesym^.name
  2095. else if hp^.paratyp=vs_var then
  2096. s:=s+'var'
  2097. else if hp^.paratyp=vs_const then
  2098. s:=s+'const';
  2099. hp:=pparaitem(hp^.previous);
  2100. if assigned(hp) then
  2101. s:=s+',';
  2102. end;
  2103. s:=s+')';
  2104. demangled_paras:=s;
  2105. end;
  2106. function tabstractprocdef.proccalloption2str : string;
  2107. type
  2108. tproccallopt=record
  2109. mask : tproccalloption;
  2110. str : string[30];
  2111. end;
  2112. const
  2113. proccallopts=12;
  2114. proccallopt : array[1..proccallopts] of tproccallopt=(
  2115. (mask:pocall_none; str:''),
  2116. (mask:pocall_clearstack; str:'ClearStack'),
  2117. (mask:pocall_leftright; str:'LeftRight'),
  2118. (mask:pocall_cdecl; str:'Cdecl'),
  2119. (mask:pocall_register; str:'Register'),
  2120. (mask:pocall_stdcall; str:'StdCall'),
  2121. (mask:pocall_safecall; str:'SafeCall'),
  2122. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2123. (mask:pocall_system; str:'System'),
  2124. (mask:pocall_inline; str:'Inline'),
  2125. (mask:pocall_internproc; str:'InternProc'),
  2126. (mask:pocall_internconst; str:'InternConst')
  2127. );
  2128. var
  2129. s : string;
  2130. i : longint;
  2131. first : boolean;
  2132. begin
  2133. s:='';
  2134. first:=true;
  2135. for i:=1to proccallopts do
  2136. if (proccallopt[i].mask in proccalloptions) then
  2137. begin
  2138. if first then
  2139. first:=false
  2140. else
  2141. s:=s+';';
  2142. s:=s+proccallopt[i].str;
  2143. end;
  2144. proccalloption2str:=s;
  2145. end;
  2146. {$ifdef GDB}
  2147. function tabstractprocdef.stabstring : pchar;
  2148. begin
  2149. stabstring := strpnew('abstractproc'+numberstring+';');
  2150. end;
  2151. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  2152. begin
  2153. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2154. and not is_def_stab_written then
  2155. begin
  2156. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2157. inherited concatstabto(asmlist);
  2158. end;
  2159. end;
  2160. {$endif GDB}
  2161. {***************************************************************************
  2162. TPROCDEF
  2163. ***************************************************************************}
  2164. constructor tprocdef.init;
  2165. begin
  2166. inherited init;
  2167. deftype:=procdef;
  2168. _mangledname:=nil;
  2169. nextoverloaded:=nil;
  2170. fileinfo:=aktfilepos;
  2171. extnumber:=-1;
  2172. localst:=new(psymtable,init(localsymtable));
  2173. parast:=new(psymtable,init(parasymtable));
  2174. localst^.defowner:=@self;
  2175. parast^.defowner:=@self;
  2176. { this is used by insert
  2177. to check same names in parast and localst }
  2178. localst^.next:=parast;
  2179. defref:=nil;
  2180. crossref:=nil;
  2181. lastwritten:=nil;
  2182. refcount:=0;
  2183. if (cs_browser in aktmoduleswitches) and make_ref then
  2184. begin
  2185. defref:=new(pref,init(defref,@tokenpos));
  2186. inc(refcount);
  2187. end;
  2188. lastref:=defref;
  2189. { first, we assume that all registers are used }
  2190. {$ifdef newcg}
  2191. usedregisters:=[firstreg..lastreg];
  2192. {$else newcg}
  2193. {$ifdef i386}
  2194. usedregisters:=$ff;
  2195. {$endif i386}
  2196. {$ifdef m68k}
  2197. usedregisters:=$FFFF;
  2198. {$endif}
  2199. {$endif newcg}
  2200. forwarddef:=true;
  2201. interfacedef:=false;
  2202. _class := nil;
  2203. code:=nil;
  2204. count:=false;
  2205. is_used:=false;
  2206. end;
  2207. constructor tprocdef.load;
  2208. var
  2209. s : string;
  2210. begin
  2211. inherited load;
  2212. deftype:=procdef;
  2213. {$ifdef newcg}
  2214. readnormalset(usedregisters);
  2215. {$else newcg}
  2216. {$ifdef i386}
  2217. usedregisters:=readbyte;
  2218. {$endif i386}
  2219. {$ifdef m68k}
  2220. usedregisters:=readword;
  2221. {$endif}
  2222. {$endif newcg}
  2223. s:=readstring;
  2224. setstring(_mangledname,s);
  2225. extnumber:=readlong;
  2226. nextoverloaded:=pprocdef(readdefref);
  2227. _class := pobjectdef(readdefref);
  2228. readposinfo(fileinfo);
  2229. if (cs_link_deffile in aktglobalswitches) and
  2230. (tf_need_export in target_info.flags) and
  2231. (po_exports in procoptions) then
  2232. deffile.AddExport(mangledname);
  2233. parast:=nil;
  2234. localst:=nil;
  2235. forwarddef:=false;
  2236. interfacedef:=false;
  2237. lastref:=nil;
  2238. lastwritten:=nil;
  2239. defref:=nil;
  2240. refcount:=0;
  2241. count:=true;
  2242. is_used:=false;
  2243. end;
  2244. Const local_symtable_index : longint = $8001;
  2245. procedure tprocdef.load_references;
  2246. var
  2247. pos : tfileposinfo;
  2248. {$ifndef NOLOCALBROWSER}
  2249. oldsymtablestack,
  2250. st : psymtable;
  2251. {$endif ndef NOLOCALBROWSER}
  2252. move_last : boolean;
  2253. begin
  2254. move_last:=lastwritten=lastref;
  2255. while (not current_ppu^.endofentry) do
  2256. begin
  2257. readposinfo(pos);
  2258. inc(refcount);
  2259. lastref:=new(pref,init(lastref,@pos));
  2260. lastref^.is_written:=true;
  2261. if refcount=1 then
  2262. defref:=lastref;
  2263. end;
  2264. if move_last then
  2265. lastwritten:=lastref;
  2266. if ((current_module^.flags and uf_local_browser)<>0)
  2267. and is_in_current then
  2268. begin
  2269. {$ifndef NOLOCALBROWSER}
  2270. oldsymtablestack:=symtablestack;
  2271. st:=aktlocalsymtable;
  2272. new(parast,loadas(parasymtable));
  2273. parast^.defowner:=@self;
  2274. aktlocalsymtable:=parast;
  2275. parast^.deref;
  2276. parast^.next:=owner;
  2277. parast^.load_browser;
  2278. aktlocalsymtable:=st;
  2279. new(localst,loadas(localsymtable));
  2280. localst^.defowner:=@self;
  2281. aktlocalsymtable:=localst;
  2282. symtablestack:=parast;
  2283. localst^.deref;
  2284. localst^.next:=parast;
  2285. localst^.load_browser;
  2286. aktlocalsymtable:=st;
  2287. symtablestack:=oldsymtablestack;
  2288. {$endif ndef NOLOCALBROWSER}
  2289. end;
  2290. end;
  2291. function tprocdef.write_references : boolean;
  2292. var
  2293. ref : pref;
  2294. {$ifndef NOLOCALBROWSER}
  2295. st : psymtable;
  2296. pdo : pobjectdef;
  2297. {$endif ndef NOLOCALBROWSER}
  2298. move_last : boolean;
  2299. begin
  2300. move_last:=lastwritten=lastref;
  2301. if move_last and (((current_module^.flags and uf_local_browser)=0)
  2302. or not is_in_current) then
  2303. exit;
  2304. { write address of this symbol }
  2305. writedefref(@self);
  2306. { write refs }
  2307. if assigned(lastwritten) then
  2308. ref:=lastwritten
  2309. else
  2310. ref:=defref;
  2311. while assigned(ref) do
  2312. begin
  2313. if ref^.moduleindex=current_module^.unit_index then
  2314. begin
  2315. writeposinfo(ref^.posinfo);
  2316. ref^.is_written:=true;
  2317. if move_last then
  2318. lastwritten:=ref;
  2319. end
  2320. else if not ref^.is_written then
  2321. move_last:=false
  2322. else if move_last then
  2323. lastwritten:=ref;
  2324. ref:=ref^.nextref;
  2325. end;
  2326. current_ppu^.writeentry(ibdefref);
  2327. write_references:=true;
  2328. if ((current_module^.flags and uf_local_browser)<>0)
  2329. and is_in_current then
  2330. begin
  2331. {$ifndef NOLOCALBROWSER}
  2332. pdo:=_class;
  2333. if (owner^.symtabletype<>localsymtable) then
  2334. while assigned(pdo) do
  2335. begin
  2336. if pdo^.symtable<>aktrecordsymtable then
  2337. begin
  2338. pdo^.symtable^.unitid:=local_symtable_index;
  2339. inc(local_symtable_index);
  2340. end;
  2341. pdo:=pdo^.childof;
  2342. end;
  2343. { we need TESTLOCALBROWSER para and local symtables
  2344. PPU files are then easier to read PM }
  2345. if not assigned(parast) then
  2346. parast:=new(psymtable,init(parasymtable));
  2347. parast^.defowner:=@self;
  2348. st:=aktlocalsymtable;
  2349. aktlocalsymtable:=parast;
  2350. parast^.writeas;
  2351. parast^.unitid:=local_symtable_index;
  2352. inc(local_symtable_index);
  2353. parast^.write_browser;
  2354. if not assigned(localst) then
  2355. localst:=new(psymtable,init(localsymtable));
  2356. localst^.defowner:=@self;
  2357. aktlocalsymtable:=localst;
  2358. localst^.writeas;
  2359. localst^.unitid:=local_symtable_index;
  2360. inc(local_symtable_index);
  2361. localst^.write_browser;
  2362. aktlocalsymtable:=st;
  2363. { decrement for }
  2364. local_symtable_index:=local_symtable_index-2;
  2365. pdo:=_class;
  2366. if (owner^.symtabletype<>localsymtable) then
  2367. while assigned(pdo) do
  2368. begin
  2369. if pdo^.symtable<>aktrecordsymtable then
  2370. dec(local_symtable_index);
  2371. pdo:=pdo^.childof;
  2372. end;
  2373. {$endif ndef NOLOCALBROWSER}
  2374. end;
  2375. end;
  2376. {$ifdef BrowserLog}
  2377. procedure tprocdef.add_to_browserlog;
  2378. begin
  2379. if assigned(defref) then
  2380. begin
  2381. browserlog.AddLog('***'+mangledname);
  2382. browserlog.AddLogRefs(defref);
  2383. if (current_module^.flags and uf_local_browser)<>0 then
  2384. begin
  2385. if assigned(parast) then
  2386. parast^.writebrowserlog;
  2387. if assigned(localst) then
  2388. localst^.writebrowserlog;
  2389. end;
  2390. end;
  2391. end;
  2392. {$endif BrowserLog}
  2393. destructor tprocdef.done;
  2394. begin
  2395. if assigned(defref) then
  2396. begin
  2397. defref^.freechain;
  2398. dispose(defref,done);
  2399. end;
  2400. if assigned(parast) then
  2401. dispose(parast,done);
  2402. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  2403. dispose(localst,done);
  2404. if (pocall_inline in proccalloptions) and assigned(code) then
  2405. disposetree(ptree(code));
  2406. if (po_msgstr in procoptions) then
  2407. strdispose(messageinf.str);
  2408. if
  2409. {$ifdef tp}
  2410. not(use_big) and
  2411. {$endif}
  2412. assigned(_mangledname) then
  2413. strdispose(_mangledname);
  2414. inherited done;
  2415. end;
  2416. procedure tprocdef.write;
  2417. begin
  2418. inherited write;
  2419. current_ppu^.do_interface_crc:=false;
  2420. { set all registers to used for simplified compilation PM }
  2421. if simplify_ppu then
  2422. begin
  2423. {$ifdef newcg}
  2424. usedregisters:=[firstreg..lastreg];
  2425. {$else newcg}
  2426. {$ifdef i386}
  2427. usedregisters:=$ff;
  2428. {$endif i386}
  2429. {$ifdef m68k}
  2430. usedregisters:=$ffff;
  2431. {$endif}
  2432. {$endif newcg}
  2433. end;
  2434. {$ifdef newcg}
  2435. writenormalset(usedregisters);
  2436. {$else newcg}
  2437. {$ifdef i386}
  2438. writebyte(usedregisters);
  2439. {$endif i386}
  2440. {$ifdef m68k}
  2441. writeword(usedregisters);
  2442. {$endif}
  2443. {$endif newcg}
  2444. current_ppu^.do_interface_crc:=true;
  2445. writestring(mangledname);
  2446. writelong(extnumber);
  2447. if (proctypeoption<>potype_operator) then
  2448. writedefref(nextoverloaded)
  2449. else
  2450. begin
  2451. { only write the overloads from the same unit }
  2452. if assigned(nextoverloaded) and
  2453. (nextoverloaded^.owner=owner) then
  2454. writedefref(nextoverloaded)
  2455. else
  2456. writedefref(nil);
  2457. end;
  2458. writedefref(_class);
  2459. writeposinfo(fileinfo);
  2460. if (pocall_inline in proccalloptions) then
  2461. begin
  2462. { we need to save
  2463. - the para and the local symtable
  2464. - the code ptree !! PM
  2465. writesymtable(parast);
  2466. writesymtable(localst);
  2467. writeptree(ptree(code));
  2468. }
  2469. end;
  2470. current_ppu^.writeentry(ibprocdef);
  2471. end;
  2472. function tprocdef.haspara:boolean;
  2473. begin
  2474. haspara:=assigned(aktprocsym^.definition^.parast^.symindex^.first);
  2475. end;
  2476. {$ifdef GDB}
  2477. procedure addparaname(p : psym);
  2478. var vs : char;
  2479. begin
  2480. if pvarsym(p)^.varspez = vs_value then vs := '1'
  2481. else vs := '0';
  2482. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.vartype.def^.numberstring+','+vs+';');
  2483. end;
  2484. function tprocdef.stabstring : pchar;
  2485. var
  2486. i : longint;
  2487. oldrec : pchar;
  2488. begin
  2489. oldrec := stabrecstring;
  2490. getmem(StabRecString,1024);
  2491. strpcopy(StabRecString,'f'+rettype.def^.numberstring);
  2492. i:=para^.count;
  2493. if i>0 then
  2494. begin
  2495. strpcopy(strend(StabRecString),','+tostr(i)+';');
  2496. (* confuse gdb !! PM
  2497. if assigned(parast) then
  2498. parast^.foreach({$ifndef TP}@{$endif}addparaname)
  2499. else
  2500. begin
  2501. param := para1;
  2502. i := 0;
  2503. while assigned(param) do
  2504. begin
  2505. inc(i);
  2506. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2507. {Here we have lost the parameter names !!}
  2508. {using lower case parameters }
  2509. strpcopy(strend(stabrecstring),'p'+tostr(i)
  2510. +':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2511. param := param^.next;
  2512. end;
  2513. end; *)
  2514. {strpcopy(strend(StabRecString),';');}
  2515. end;
  2516. stabstring := strnew(stabrecstring);
  2517. freemem(stabrecstring,1024);
  2518. stabrecstring := oldrec;
  2519. end;
  2520. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  2521. begin
  2522. end;
  2523. {$endif GDB}
  2524. procedure tprocdef.deref;
  2525. begin
  2526. inherited deref;
  2527. resolvedef(pdef(nextoverloaded));
  2528. resolvedef(pdef(_class));
  2529. end;
  2530. function tprocdef.mangledname : string;
  2531. {$ifdef tp}
  2532. var
  2533. oldpos : longint;
  2534. s : string;
  2535. b : byte;
  2536. {$endif tp}
  2537. begin
  2538. {$ifndef Delphi}
  2539. {$ifdef tp}
  2540. if use_big then
  2541. begin
  2542. symbolstream.seek(longint(_mangledname));
  2543. symbolstream.read(b,1);
  2544. symbolstream.read(s[1],b);
  2545. s[0]:=chr(b);
  2546. mangledname:=s;
  2547. end
  2548. else
  2549. {$endif}
  2550. {$endif Delphi}
  2551. mangledname:=strpas(_mangledname);
  2552. if count then
  2553. is_used:=true;
  2554. end;
  2555. function tprocdef.procname: string;
  2556. var
  2557. s : string;
  2558. l : longint;
  2559. begin
  2560. s:=mangledname;
  2561. { delete leading $$'s }
  2562. l:=pos('$$',s);
  2563. while l<>0 do
  2564. begin
  2565. delete(s,1,l+1);
  2566. l:=pos('$$',s);
  2567. end;
  2568. { delete leading _$'s }
  2569. l:=pos('_$',s);
  2570. while l<>0 do
  2571. begin
  2572. delete(s,1,l+1);
  2573. l:=pos('_$',s);
  2574. end;
  2575. l:=pos('$',s);
  2576. if l=0 then
  2577. procname:=s
  2578. else
  2579. procname:=Copy(s,1,l-1);
  2580. end;
  2581. {$IfDef GDB}
  2582. function tprocdef.cplusplusmangledname : string;
  2583. var
  2584. s,s2 : string;
  2585. param : pparaitem;
  2586. begin
  2587. s := typesym^.name;
  2588. if _class <> nil then
  2589. begin
  2590. s2 := _class^.objname^;
  2591. s := s+'__'+tostr(length(s2))+s2;
  2592. end else s := s + '_';
  2593. param := pparaitem(para^.first);
  2594. while assigned(param) do
  2595. begin
  2596. s2 := param^.paratype.def^.typesym^.name;
  2597. s := s+tostr(length(s2))+s2;
  2598. param := pparaitem(param^.next);
  2599. end;
  2600. cplusplusmangledname:=s;
  2601. end;
  2602. {$EndIf GDB}
  2603. procedure tprocdef.setmangledname(const s : string);
  2604. begin
  2605. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  2606. strdispose(_mangledname);
  2607. setstring(_mangledname,s);
  2608. if assigned(parast) then
  2609. begin
  2610. stringdispose(parast^.name);
  2611. parast^.name:=stringdup('args of '+s);
  2612. end;
  2613. if assigned(localst) then
  2614. begin
  2615. stringdispose(localst^.name);
  2616. localst^.name:=stringdup('locals of '+s);
  2617. end;
  2618. end;
  2619. {***************************************************************************
  2620. TPROCVARDEF
  2621. ***************************************************************************}
  2622. constructor tprocvardef.init;
  2623. begin
  2624. inherited init;
  2625. deftype:=procvardef;
  2626. end;
  2627. constructor tprocvardef.load;
  2628. begin
  2629. inherited load;
  2630. deftype:=procvardef;
  2631. end;
  2632. procedure tprocvardef.write;
  2633. begin
  2634. { here we cannot get a real good value so just give something }
  2635. { plausible (PM) }
  2636. { a more secure way would be
  2637. to allways store in a temp }
  2638. if is_fpu(rettype.def) then
  2639. fpu_used:=2
  2640. else
  2641. fpu_used:=0;
  2642. inherited write;
  2643. current_ppu^.writeentry(ibprocvardef);
  2644. end;
  2645. function tprocvardef.size : longint;
  2646. begin
  2647. if (po_methodpointer in procoptions) then
  2648. size:=2*target_os.size_of_pointer
  2649. else
  2650. size:=target_os.size_of_pointer;
  2651. end;
  2652. {$ifdef GDB}
  2653. function tprocvardef.stabstring : pchar;
  2654. var
  2655. nss : pchar;
  2656. { i : longint; }
  2657. begin
  2658. { i := para^.count; }
  2659. getmem(nss,1024);
  2660. { it is not a function but a function pointer !! (PM) }
  2661. strpcopy(nss,'*f'+rettype.def^.numberstring{+','+tostr(i)}+';');
  2662. { this confuses gdb !!
  2663. we should use 'F' instead of 'f' but
  2664. as we use c++ language mode
  2665. it does not like that either
  2666. Please do not remove this part
  2667. might be used once
  2668. gdb for pascal is ready PM }
  2669. (*
  2670. param := para1;
  2671. i := 0;
  2672. while assigned(param) do
  2673. begin
  2674. inc(i);
  2675. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2676. {Here we have lost the parameter names !!}
  2677. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2678. strcat(nss,pst);
  2679. strdispose(pst);
  2680. param := param^.next;
  2681. end; *)
  2682. {strpcopy(strend(nss),';');}
  2683. stabstring := strnew(nss);
  2684. freemem(nss,1024);
  2685. end;
  2686. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2687. begin
  2688. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2689. and not is_def_stab_written then
  2690. inherited concatstabto(asmlist);
  2691. is_def_stab_written:=true;
  2692. end;
  2693. {$endif GDB}
  2694. procedure tprocvardef.write_rtti_data;
  2695. var
  2696. pdc : pparaitem;
  2697. methodkind, paraspec : byte;
  2698. begin
  2699. if po_methodpointer in procoptions then
  2700. begin
  2701. { write method id and name }
  2702. rttilist^.concat(new(pai_const,init_8bit(tkmethod)));
  2703. write_rtti_name;
  2704. { write kind of method (can only be function or procedure)}
  2705. if rettype.def = pdef(voiddef) then { ### typecast shoudln't be necessary! (sg) }
  2706. methodkind := mkProcedure
  2707. else
  2708. methodkind := mkFunction;
  2709. rttilist^.concat(new(pai_const,init_8bit(methodkind)));
  2710. { get # of parameters }
  2711. rttilist^.concat(new(pai_const,init_8bit(para^.count)));
  2712. { write parameter info. The parameters must be written in reverse order
  2713. if this method uses right to left parameter pushing! }
  2714. if (pocall_leftright in proccalloptions) then
  2715. pdc:=pparaitem(para^.last)
  2716. else
  2717. pdc:=pparaitem(para^.first);
  2718. while assigned(pdc) do
  2719. begin
  2720. case pdc^.paratyp of
  2721. vs_value: paraspec := 0;
  2722. vs_const: paraspec := pfConst;
  2723. vs_var : paraspec := pfVar;
  2724. end;
  2725. { write flags for current parameter }
  2726. rttilist^.concat(new(pai_const,init_8bit(paraspec)));
  2727. { write name of current parameter ### how can I get this??? (sg)}
  2728. rttilist^.concat(new(pai_const,init_8bit(0)));
  2729. { write name of type of current parameter }
  2730. pdc^.paratype.def^.write_rtti_name;
  2731. if (pocall_leftright in proccalloptions) then
  2732. pdc:=pparaitem(pdc^.previous)
  2733. else
  2734. pdc:=pparaitem(pdc^.next);
  2735. end;
  2736. { write name of result type }
  2737. rettype.def^.write_rtti_name;
  2738. end;
  2739. end;
  2740. procedure tprocvardef.write_child_rtti_data;
  2741. begin
  2742. {!!!!!!!!}
  2743. end;
  2744. function tprocvardef.is_publishable : boolean;
  2745. begin
  2746. is_publishable:=(po_methodpointer in procoptions);
  2747. end;
  2748. function tprocvardef.gettypename : string;
  2749. begin
  2750. if assigned(rettype.def) and
  2751. (rettype.def<>pdef(voiddef)) then
  2752. gettypename:='<procedure variable type of function'+demangled_paras+
  2753. ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
  2754. else
  2755. gettypename:='<procedure variable type of procedure'+demangled_paras+
  2756. ';'+proccalloption2str+'>';
  2757. end;
  2758. {***************************************************************************
  2759. TOBJECTDEF
  2760. ***************************************************************************}
  2761. {$ifdef GDB}
  2762. const
  2763. vtabletype : word = 0;
  2764. vtableassigned : boolean = false;
  2765. {$endif GDB}
  2766. constructor tobjectdef.init(const n : string;c : pobjectdef);
  2767. begin
  2768. tdef.init;
  2769. deftype:=objectdef;
  2770. objectoptions:=[];
  2771. childof:=nil;
  2772. symtable:=new(psymtable,init(objectsymtable));
  2773. symtable^.name := stringdup(n);
  2774. { create space for vmt !! }
  2775. vmt_offset:=0;
  2776. symtable^.datasize:=0;
  2777. symtable^.defowner:=@self;
  2778. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  2779. set_parent(c);
  2780. objname:=stringdup(n);
  2781. end;
  2782. constructor tobjectdef.load;
  2783. var
  2784. oldread_member : boolean;
  2785. begin
  2786. tdef.load;
  2787. deftype:=objectdef;
  2788. savesize:=readlong;
  2789. vmt_offset:=readlong;
  2790. objname:=stringdup(readstring);
  2791. childof:=pobjectdef(readdefref);
  2792. readsmallset(objectoptions);
  2793. has_rtti:=boolean(readbyte);
  2794. oldread_member:=read_member;
  2795. read_member:=true;
  2796. symtable:=new(psymtable,loadas(objectsymtable));
  2797. read_member:=oldread_member;
  2798. symtable^.defowner:=@self;
  2799. symtable^.name := stringdup(objname^);
  2800. { handles the predefined class tobject }
  2801. { the last TOBJECT which is loaded gets }
  2802. { it ! }
  2803. if (childof=nil) and
  2804. is_class and
  2805. (objname^='TOBJECT') then
  2806. class_tobject:=@self;
  2807. end;
  2808. destructor tobjectdef.done;
  2809. begin
  2810. if assigned(symtable) then
  2811. dispose(symtable,done);
  2812. if (oo_is_forward in objectoptions) then
  2813. Message1(sym_e_class_forward_not_resolved,objname^);
  2814. stringdispose(objname);
  2815. tdef.done;
  2816. end;
  2817. procedure tobjectdef.write;
  2818. var
  2819. oldread_member : boolean;
  2820. begin
  2821. tdef.write;
  2822. writelong(size);
  2823. writelong(vmt_offset);
  2824. writestring(objname^);
  2825. writedefref(childof);
  2826. writesmallset(objectoptions);
  2827. writebyte(byte(has_rtti));
  2828. current_ppu^.writeentry(ibobjectdef);
  2829. oldread_member:=read_member;
  2830. read_member:=true;
  2831. symtable^.writeas;
  2832. read_member:=oldread_member;
  2833. end;
  2834. procedure tobjectdef.deref;
  2835. var
  2836. oldrecsyms : psymtable;
  2837. begin
  2838. inherited deref;
  2839. resolvedef(pdef(childof));
  2840. oldrecsyms:=aktrecordsymtable;
  2841. aktrecordsymtable:=symtable;
  2842. symtable^.deref;
  2843. aktrecordsymtable:=oldrecsyms;
  2844. end;
  2845. procedure tobjectdef.set_parent( c : pobjectdef);
  2846. begin
  2847. { nothing to do if the parent was not forward !}
  2848. if assigned(childof) then
  2849. exit;
  2850. childof:=c;
  2851. { some options are inherited !! }
  2852. if assigned(c) then
  2853. begin
  2854. objectoptions:=objectoptions+(c^.objectoptions*
  2855. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  2856. { add the data of the anchestor class }
  2857. inc(symtable^.datasize,c^.symtable^.datasize);
  2858. if (oo_has_vmt in objectoptions) and
  2859. (oo_has_vmt in c^.objectoptions) then
  2860. dec(symtable^.datasize,target_os.size_of_pointer);
  2861. { if parent has a vmt field then
  2862. the offset is the same for the child PM }
  2863. if (oo_has_vmt in c^.objectoptions) or is_class then
  2864. begin
  2865. vmt_offset:=c^.vmt_offset;
  2866. {$ifdef INCLUDEOK}
  2867. include(objectoptions,oo_has_vmt);
  2868. {$else}
  2869. objectoptions:=objectoptions+[oo_has_vmt];
  2870. {$endif}
  2871. end;
  2872. end;
  2873. savesize := symtable^.datasize;
  2874. end;
  2875. procedure tobjectdef.insertvmt;
  2876. begin
  2877. if (oo_has_vmt in objectoptions) then
  2878. internalerror(12345)
  2879. else
  2880. begin
  2881. { first round up to multiple of 4 }
  2882. if (symtable^.dataalignment=2) then
  2883. begin
  2884. if (symtable^.datasize and 1)<>0 then
  2885. inc(symtable^.datasize);
  2886. end
  2887. else
  2888. if (symtable^.dataalignment>=4) then
  2889. begin
  2890. if (symtable^.datasize mod 4) <> 0 then
  2891. inc(symtable^.datasize,4-(symtable^.datasize mod 4));
  2892. end;
  2893. vmt_offset:=symtable^.datasize;
  2894. inc(symtable^.datasize,target_os.size_of_pointer);
  2895. include(objectoptions,oo_has_vmt);
  2896. end;
  2897. end;
  2898. procedure tobjectdef.check_forwards;
  2899. begin
  2900. symtable^.check_forwards;
  2901. if (oo_is_forward in objectoptions) then
  2902. begin
  2903. { ok, in future, the forward can be resolved }
  2904. Message1(sym_e_class_forward_not_resolved,objname^);
  2905. {$ifdef INCLUDEOK}
  2906. exclude(objectoptions,oo_is_forward);
  2907. {$else}
  2908. objectoptions:=objectoptions-[oo_is_forward];
  2909. {$endif}
  2910. end;
  2911. end;
  2912. { true, if self inherits from d (or if they are equal) }
  2913. function tobjectdef.is_related(d : pobjectdef) : boolean;
  2914. var
  2915. hp : pobjectdef;
  2916. begin
  2917. hp:=@self;
  2918. while assigned(hp) do
  2919. begin
  2920. if hp=d then
  2921. begin
  2922. is_related:=true;
  2923. exit;
  2924. end;
  2925. hp:=hp^.childof;
  2926. end;
  2927. is_related:=false;
  2928. end;
  2929. var
  2930. sd : pprocdef;
  2931. procedure _searchdestructor(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  2932. var
  2933. p : pprocdef;
  2934. begin
  2935. { if we found already a destructor, then we exit }
  2936. if assigned(sd) then
  2937. exit;
  2938. if psym(sym)^.typ=procsym then
  2939. begin
  2940. p:=pprocsym(sym)^.definition;
  2941. while assigned(p) do
  2942. begin
  2943. if p^.proctypeoption=potype_destructor then
  2944. begin
  2945. sd:=p;
  2946. exit;
  2947. end;
  2948. p:=p^.nextoverloaded;
  2949. end;
  2950. end;
  2951. end;
  2952. function tobjectdef.searchdestructor : pprocdef;
  2953. var
  2954. o : pobjectdef;
  2955. begin
  2956. searchdestructor:=nil;
  2957. o:=@self;
  2958. sd:=nil;
  2959. while assigned(o) do
  2960. begin
  2961. symtable^.foreach({$ifndef TP}@{$endif}_searchdestructor);
  2962. if assigned(sd) then
  2963. begin
  2964. searchdestructor:=sd;
  2965. exit;
  2966. end;
  2967. o:=o^.childof;
  2968. end;
  2969. end;
  2970. function tobjectdef.size : longint;
  2971. begin
  2972. if (oo_is_class in objectoptions) then
  2973. size:=target_os.size_of_pointer
  2974. else
  2975. size:=symtable^.datasize;
  2976. end;
  2977. function tobjectdef.alignment:longint;
  2978. begin
  2979. alignment:=symtable^.dataalignment;
  2980. end;
  2981. function tobjectdef.vmtmethodoffset(index:longint):longint;
  2982. begin
  2983. { for offset of methods for classes, see rtl/inc/objpash.inc }
  2984. if is_class then
  2985. vmtmethodoffset:=(index+12)*target_os.size_of_pointer
  2986. else
  2987. {$ifdef WITHDMT}
  2988. vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
  2989. {$else WITHDMT}
  2990. vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
  2991. {$endif WITHDMT}
  2992. end;
  2993. function tobjectdef.vmt_mangledname : string;
  2994. {DM: I get a nil pointer on the owner name. I don't know if this
  2995. mayhappen, and I have therefore fixed the problem by doing nil pointer
  2996. checks.}
  2997. var
  2998. s1,s2:string;
  2999. begin
  3000. if not(oo_has_vmt in objectoptions) then
  3001. Message1(parser_object_has_no_vmt,objname^);
  3002. if owner^.name=nil then
  3003. s1:=''
  3004. else
  3005. s1:=owner^.name^;
  3006. if objname=nil then
  3007. s2:=''
  3008. else
  3009. s2:=objname^;
  3010. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3011. end;
  3012. function tobjectdef.rtti_name : string;
  3013. var
  3014. s1,s2:string;
  3015. begin
  3016. if owner^.name=nil then
  3017. s1:=''
  3018. else
  3019. s1:=owner^.name^;
  3020. if objname=nil then
  3021. s2:=''
  3022. else
  3023. s2:=objname^;
  3024. rtti_name:='RTTI_'+s1+'$_'+s2;
  3025. end;
  3026. function tobjectdef.is_class : boolean;
  3027. begin
  3028. is_class:=(oo_is_class in objectoptions);
  3029. end;
  3030. {$ifdef GDB}
  3031. procedure addprocname(p :pnamedindexobject);
  3032. var virtualind,argnames : string;
  3033. news, newrec : pchar;
  3034. pd,ipd : pprocdef;
  3035. lindex : longint;
  3036. para : pparaitem;
  3037. arglength : byte;
  3038. sp : char;
  3039. begin
  3040. If psym(p)^.typ = procsym then
  3041. begin
  3042. pd := pprocsym(p)^.definition;
  3043. { this will be used for full implementation of object stabs
  3044. not yet done }
  3045. ipd := pd;
  3046. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  3047. if (po_virtualmethod in pd^.procoptions) then
  3048. begin
  3049. lindex := pd^.extnumber;
  3050. {doesnt seem to be necessary
  3051. lindex := lindex or $80000000;}
  3052. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  3053. end else virtualind := '.';
  3054. { used by gdbpas to recognize constructor and destructors }
  3055. if (pd^.proctypeoption=potype_constructor) then
  3056. argnames:='__ct__'
  3057. else if (pd^.proctypeoption=potype_destructor) then
  3058. argnames:='__dt__'
  3059. else
  3060. argnames := '';
  3061. { arguments are not listed here }
  3062. {we don't need another definition}
  3063. para := pparaitem(pd^.para^.first);
  3064. while assigned(para) do
  3065. begin
  3066. if para^.paratype.def^.deftype = formaldef then
  3067. begin
  3068. if para^.paratyp=vs_var then
  3069. argnames := argnames+'3var'
  3070. else if para^.paratyp=vs_const then
  3071. argnames:=argnames+'5const';
  3072. end
  3073. else
  3074. begin
  3075. { if the arg definition is like (v: ^byte;..
  3076. there is no sym attached to data !!! }
  3077. if assigned(para^.paratype.def^.typesym) then
  3078. begin
  3079. arglength := length(para^.paratype.def^.typesym^.name);
  3080. argnames := argnames + tostr(arglength)+para^.paratype.def^.typesym^.name;
  3081. end
  3082. else
  3083. begin
  3084. argnames:=argnames+'11unnamedtype';
  3085. end;
  3086. end;
  3087. para := pparaitem(para^.next);
  3088. end;
  3089. ipd^.is_def_stab_written := true;
  3090. { here 2A must be changed for private and protected }
  3091. { 0 is private 1 protected and 2 public }
  3092. if (sp_private in psym(p)^.symoptions) then sp:='0'
  3093. else if (sp_protected in psym(p)^.symoptions) then sp:='1'
  3094. else sp:='2';
  3095. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  3096. +'=##'+pd^.rettype.def^.numberstring+';:'+argnames+';'+sp+'A'
  3097. +virtualind+';');
  3098. { get spare place for a string at the end }
  3099. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3100. begin
  3101. getmem(news,stabrecsize+memsizeinc);
  3102. strcopy(news,stabrecstring);
  3103. freemem(stabrecstring,stabrecsize);
  3104. stabrecsize:=stabrecsize+memsizeinc;
  3105. stabrecstring:=news;
  3106. end;
  3107. strcat(StabRecstring,newrec);
  3108. {freemem(newrec,memsizeinc); }
  3109. strdispose(newrec);
  3110. {This should be used for case !!}
  3111. RecOffset := RecOffset + pd^.size;
  3112. end;
  3113. end;
  3114. function tobjectdef.stabstring : pchar;
  3115. var anc : pobjectdef;
  3116. oldrec : pchar;
  3117. oldrecsize : longint;
  3118. str_end : string;
  3119. begin
  3120. oldrec := stabrecstring;
  3121. oldrecsize:=stabrecsize;
  3122. stabrecsize:=memsizeinc;
  3123. GetMem(stabrecstring,stabrecsize);
  3124. strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
  3125. if assigned(childof) then
  3126. {only one ancestor not virtual, public, at base offset 0 }
  3127. { !1 , 0 2 0 , }
  3128. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  3129. {virtual table to implement yet}
  3130. RecOffset := 0;
  3131. symtable^.foreach({$ifndef TP}@{$endif}addname);
  3132. if (oo_has_vmt in objectoptions) then
  3133. if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
  3134. begin
  3135. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')
  3136. +','+tostr(vmt_offset*8)+';');
  3137. end;
  3138. symtable^.foreach({$ifndef TP}@{$endif}addprocname);
  3139. if (oo_has_vmt in objectoptions) then
  3140. begin
  3141. anc := @self;
  3142. while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
  3143. anc := anc^.childof;
  3144. str_end:=';~%'+anc^.numberstring+';';
  3145. end
  3146. else
  3147. str_end:=';';
  3148. strpcopy(strend(stabrecstring),str_end);
  3149. stabstring := strnew(StabRecString);
  3150. freemem(stabrecstring,stabrecsize);
  3151. stabrecstring := oldrec;
  3152. stabrecsize:=oldrecsize;
  3153. end;
  3154. {$endif GDB}
  3155. procedure tobjectdef.write_child_init_data;
  3156. begin
  3157. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  3158. end;
  3159. procedure tobjectdef.write_init_data;
  3160. begin
  3161. if is_class then
  3162. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3163. else
  3164. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3165. { generate the name }
  3166. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3167. rttilist^.concat(new(pai_string,init(objname^)));
  3168. rttilist^.concat(new(pai_const,init_32bit(size)));
  3169. count:=0;
  3170. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  3171. rttilist^.concat(new(pai_const,init_32bit(count)));
  3172. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  3173. end;
  3174. function tobjectdef.needs_inittable : boolean;
  3175. var
  3176. oldb : boolean;
  3177. begin
  3178. if is_class then
  3179. needs_inittable:=false
  3180. else
  3181. begin
  3182. { there are recursive calls to needs_inittable possible, }
  3183. { so we have to change to old value how else should }
  3184. { we do that ? check_rec_rtti can't be a nested }
  3185. { procedure of needs_rtti ! }
  3186. oldb:=binittable;
  3187. binittable:=false;
  3188. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  3189. needs_inittable:=binittable;
  3190. binittable:=oldb;
  3191. end;
  3192. end;
  3193. procedure count_published_properties(sym:pnamedindexobject);
  3194. {$ifndef fpc}far;{$endif}
  3195. begin
  3196. if needs_prop_entry(psym(sym)) and
  3197. (psym(sym)^.typ<>varsym) then
  3198. inc(count);
  3199. end;
  3200. procedure write_property_info(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3201. var
  3202. proctypesinfo : byte;
  3203. procedure writeproc(proc : psymlist; shiftvalue : byte);
  3204. var
  3205. typvalue : byte;
  3206. hp : psymlistitem;
  3207. address : longint;
  3208. begin
  3209. if not(assigned(proc) and assigned(proc^.firstsym)) then
  3210. begin
  3211. rttilist^.concat(new(pai_const,init_32bit(1)));
  3212. typvalue:=3;
  3213. end
  3214. else if proc^.firstsym^.sym^.typ=varsym then
  3215. begin
  3216. address:=0;
  3217. hp:=proc^.firstsym;
  3218. while assigned(hp) do
  3219. begin
  3220. inc(address,pvarsym(hp^.sym)^.address);
  3221. hp:=hp^.next;
  3222. end;
  3223. rttilist^.concat(new(pai_const,init_32bit(address)));
  3224. typvalue:=0;
  3225. end
  3226. else
  3227. begin
  3228. if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
  3229. begin
  3230. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(proc^.def)^.mangledname)));
  3231. typvalue:=1;
  3232. end
  3233. else
  3234. begin
  3235. { virtual method, write vmt offset }
  3236. rttilist^.concat(new(pai_const,init_32bit(
  3237. pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber))));
  3238. typvalue:=2;
  3239. end;
  3240. end;
  3241. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  3242. end;
  3243. begin
  3244. if needs_prop_entry(psym(sym)) then
  3245. case psym(sym)^.typ of
  3246. varsym:
  3247. begin
  3248. {$ifdef dummy}
  3249. if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
  3250. not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
  3251. internalerror(1509992);
  3252. { access to implicit class property as field }
  3253. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  3254. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  3255. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3256. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3257. { per default stored }
  3258. rttilist^.concat(new(pai_const,init_32bit(1)));
  3259. { index as well as ... }
  3260. rttilist^.concat(new(pai_const,init_32bit(0)));
  3261. { default value are zero }
  3262. rttilist^.concat(new(pai_const,init_32bit(0)));
  3263. rttilist^.concat(new(pai_const,init_16bit(count)));
  3264. inc(count);
  3265. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3266. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3267. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3268. {$endif dummy}
  3269. end;
  3270. propertysym:
  3271. begin
  3272. if ppo_indexed in ppropertysym(sym)^.propoptions then
  3273. proctypesinfo:=$40
  3274. else
  3275. proctypesinfo:=0;
  3276. rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype.def^.get_rtti_label)));
  3277. writeproc(ppropertysym(sym)^.readaccess,0);
  3278. writeproc(ppropertysym(sym)^.writeaccess,2);
  3279. { isn't it stored ? }
  3280. if not(ppo_stored in ppropertysym(sym)^.propoptions) then
  3281. begin
  3282. rttilist^.concat(new(pai_const,init_32bit(0)));
  3283. proctypesinfo:=proctypesinfo or (3 shl 4);
  3284. end
  3285. else
  3286. writeproc(ppropertysym(sym)^.storedaccess,4);
  3287. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  3288. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  3289. rttilist^.concat(new(pai_const,init_16bit(count)));
  3290. inc(count);
  3291. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3292. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.name))));
  3293. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  3294. end;
  3295. else internalerror(1509992);
  3296. end;
  3297. end;
  3298. procedure generate_published_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3299. begin
  3300. if needs_prop_entry(psym(sym)) then
  3301. case psym(sym)^.typ of
  3302. varsym:
  3303. ;
  3304. { now ignored:
  3305. pvarsym(sym)^.vartype.def^.get_rtti_label;
  3306. }
  3307. propertysym:
  3308. ppropertysym(sym)^.proptype.def^.get_rtti_label;
  3309. else
  3310. internalerror(1509991);
  3311. end;
  3312. end;
  3313. procedure tobjectdef.write_child_rtti_data;
  3314. begin
  3315. symtable^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
  3316. end;
  3317. procedure tobjectdef.generate_rtti;
  3318. begin
  3319. if not has_rtti then
  3320. begin
  3321. has_rtti:=true;
  3322. getdatalabel(rtti_label);
  3323. write_child_rtti_data;
  3324. rttilist^.concat(new(pai_symbol,initname_global(rtti_name,0)));
  3325. rttilist^.concat(new(pai_label,init(rtti_label)));
  3326. write_rtti_data;
  3327. rttilist^.concat(new(pai_symbol_end,initname(rtti_name)));
  3328. end;
  3329. end;
  3330. type
  3331. tclasslistitem = object(tlinkedlist_item)
  3332. index : longint;
  3333. p : pobjectdef;
  3334. end;
  3335. pclasslistitem = ^tclasslistitem;
  3336. var
  3337. classtablelist : tlinkedlist;
  3338. tablecount : longint;
  3339. function searchclasstablelist(p : pobjectdef) : pclasslistitem;
  3340. var
  3341. hp : pclasslistitem;
  3342. begin
  3343. hp:=pclasslistitem(classtablelist.first);
  3344. while assigned(hp) do
  3345. if hp^.p=p then
  3346. begin
  3347. searchclasstablelist:=hp;
  3348. exit;
  3349. end
  3350. else
  3351. hp:=pclasslistitem(hp^.next);
  3352. searchclasstablelist:=nil;
  3353. end;
  3354. procedure count_published_fields(sym:pnamedindexobject);
  3355. {$ifndef fpc}far;{$endif}
  3356. var
  3357. hp : pclasslistitem;
  3358. begin
  3359. if needs_prop_entry(psym(sym)) and
  3360. (psym(sym)^.typ=varsym) then
  3361. begin
  3362. if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
  3363. internalerror(0206001);
  3364. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3365. if not(assigned(hp)) then
  3366. begin
  3367. hp:=new(pclasslistitem,init);
  3368. hp^.p:=pobjectdef(pvarsym(sym)^.vartype.def);
  3369. hp^.index:=tablecount;
  3370. classtablelist.concat(hp);
  3371. inc(tablecount);
  3372. end;
  3373. inc(count);
  3374. end;
  3375. end;
  3376. procedure writefields(sym:pnamedindexobject);
  3377. {$ifndef fpc}far;{$endif}
  3378. var
  3379. hp : pclasslistitem;
  3380. begin
  3381. if needs_prop_entry(psym(sym)) and
  3382. (psym(sym)^.typ=varsym) then
  3383. begin
  3384. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3385. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3386. if not(assigned(hp)) then
  3387. internalerror(0206002);
  3388. rttilist^.concat(new(pai_const,init_32bit(hp^.index)));
  3389. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3390. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3391. end;
  3392. end;
  3393. function tobjectdef.generate_field_table : pasmlabel;
  3394. var
  3395. fieldtable,
  3396. classtable : pasmlabel;
  3397. hp : pclasslistitem;
  3398. begin
  3399. classtablelist.init;
  3400. getlabel(fieldtable);
  3401. getlabel(classtable);
  3402. count:=0;
  3403. tablecount:=0;
  3404. symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
  3405. rttilist^.concat(new(pai_label,init(fieldtable)));
  3406. rttilist^.concat(new(pai_const,init_16bit(count)));
  3407. rttilist^.concat(new(pai_const_symbol,init(classtable)));
  3408. symtable^.foreach({$ifdef FPC}@{$endif}writefields);
  3409. { generate the class table }
  3410. rttilist^.concat(new(pai_label,init(classtable)));
  3411. rttilist^.concat(new(pai_const,init_16bit(tablecount)));
  3412. hp:=pclasslistitem(classtablelist.first);
  3413. while assigned(hp) do
  3414. begin
  3415. rttilist^.concat(new(pai_const_symbol,initname(pobjectdef(hp^.p)^.vmt_mangledname)));
  3416. hp:=pclasslistitem(hp^.next);
  3417. end;
  3418. generate_field_table:=fieldtable;
  3419. classtablelist.done;
  3420. end;
  3421. function tobjectdef.next_free_name_index : longint;
  3422. var
  3423. i : longint;
  3424. begin
  3425. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3426. i:=childof^.next_free_name_index
  3427. else
  3428. i:=0;
  3429. count:=0;
  3430. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3431. next_free_name_index:=i+count;
  3432. end;
  3433. procedure tobjectdef.write_rtti_data;
  3434. begin
  3435. if is_class then
  3436. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3437. else
  3438. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3439. { generate the name }
  3440. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3441. rttilist^.concat(new(pai_string,init(objname^)));
  3442. { write class type }
  3443. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  3444. { write owner typeinfo }
  3445. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3446. rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
  3447. else
  3448. rttilist^.concat(new(pai_const,init_32bit(0)));
  3449. { count total number of properties }
  3450. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3451. count:=childof^.next_free_name_index
  3452. else
  3453. count:=0;
  3454. { write it }
  3455. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3456. rttilist^.concat(new(pai_const,init_16bit(count)));
  3457. { write unit name }
  3458. if assigned(owner^.name) then
  3459. begin
  3460. rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
  3461. rttilist^.concat(new(pai_string,init(owner^.name^)));
  3462. end
  3463. else
  3464. rttilist^.concat(new(pai_const,init_8bit(0)));
  3465. { write published properties count }
  3466. count:=0;
  3467. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3468. rttilist^.concat(new(pai_const,init_16bit(count)));
  3469. { count is used to write nameindex }
  3470. { but we need an offset of the owner }
  3471. { to give each property an own slot }
  3472. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3473. count:=childof^.next_free_name_index
  3474. else
  3475. count:=0;
  3476. symtable^.foreach({$ifndef TP}@{$endif}write_property_info);
  3477. end;
  3478. function tobjectdef.is_publishable : boolean;
  3479. begin
  3480. is_publishable:=is_class;
  3481. end;
  3482. function tobjectdef.get_rtti_label : string;
  3483. begin
  3484. generate_rtti;
  3485. get_rtti_label:=rtti_name;
  3486. end;
  3487. {****************************************************************************
  3488. TFORWARDDEF
  3489. ****************************************************************************}
  3490. constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
  3491. var
  3492. oldregisterdef : boolean;
  3493. begin
  3494. { never register the forwarddefs, they are disposed at the
  3495. end of the type declaration block }
  3496. oldregisterdef:=registerdef;
  3497. registerdef:=false;
  3498. inherited init;
  3499. registerdef:=oldregisterdef;
  3500. deftype:=forwarddef;
  3501. tosymname:=s;
  3502. forwardpos:=pos;
  3503. end;
  3504. function tforwarddef.gettypename:string;
  3505. begin
  3506. gettypename:='unresolved forward to '+tosymname;
  3507. end;
  3508. {****************************************************************************
  3509. TERRORDEF
  3510. ****************************************************************************}
  3511. constructor terrordef.init;
  3512. begin
  3513. inherited init;
  3514. deftype:=errordef;
  3515. end;
  3516. {$ifdef GDB}
  3517. function terrordef.stabstring : pchar;
  3518. begin
  3519. stabstring:=strpnew('error'+numberstring);
  3520. end;
  3521. {$endif GDB}
  3522. function terrordef.gettypename:string;
  3523. begin
  3524. gettypename:='<erroneous type>';
  3525. end;
  3526. {
  3527. $Log$
  3528. Revision 1.201 2000-06-18 18:11:32 peter
  3529. * C record packing fixed to also check first entry of the record
  3530. if bigger than the recordalignment itself
  3531. * variant record alignment uses alignment per variant and saves the
  3532. highest alignment value
  3533. Revision 1.200 2000/06/02 18:48:47 florian
  3534. + fieldtable support for classes
  3535. Revision 1.199 2000/04/01 14:17:08 peter
  3536. * arraydef.elesize returns 4 when strings are found in an openarray,
  3537. arrayconstructor. Since only the pointers to the strings are stored
  3538. Revision 1.198 2000/04/01 11:44:56 peter
  3539. * fixed rtti info for record
  3540. Revision 1.197 2000/03/01 12:35:45 pierre
  3541. * fix for bug 855
  3542. Revision 1.196 2000/02/14 20:58:43 marco
  3543. * Basic structures for new sethandling implemented.
  3544. Revision 1.195 2000/02/11 13:53:49 pierre
  3545. * avoid stack overflow in tref.done (bug 846)
  3546. Revision 1.194 2000/02/09 13:23:04 peter
  3547. * log truncated
  3548. Revision 1.193 2000/02/05 14:33:32 florian
  3549. * fixed init table generation for classes and arrays
  3550. Revision 1.192 2000/02/04 20:00:22 florian
  3551. * an exception in a construcor calls now the destructor (this applies only
  3552. to classes)
  3553. Revision 1.191 2000/01/30 23:29:06 peter
  3554. * fixed dup rtti writing for classes
  3555. Revision 1.190 2000/01/28 23:17:53 florian
  3556. * virtual XXXX; support for objects, only if -dWITHDMT is defined
  3557. Revision 1.189 2000/01/26 12:02:29 peter
  3558. * abstractprocdef.para_size needs alignment parameter
  3559. * secondcallparan gets para_alignment size instead of dword_align
  3560. Revision 1.188 2000/01/23 16:35:31 peter
  3561. * localbrowser loading of absolute fixed. It needed a symtablestack
  3562. which was not setup correctly
  3563. Revision 1.187 2000/01/09 23:16:06 peter
  3564. * added st_default stringtype
  3565. * genstringconstnode extended with stringtype parameter using st_default
  3566. will do the old behaviour
  3567. Revision 1.186 2000/01/07 01:14:39 peter
  3568. * updated copyright to 2000
  3569. Revision 1.185 2000/01/03 19:26:03 peter
  3570. * fixed resolving of ttypesym which are reference from object/record
  3571. fields.
  3572. Revision 1.184 1999/12/31 14:24:34 peter
  3573. * fixed rtti generation for classes with no published section
  3574. Revision 1.183 1999/12/23 12:19:42 peter
  3575. * check_rec_inittable fix from sg
  3576. Revision 1.182 1999/12/19 17:00:27 peter
  3577. * has_rtti should be saved in the ppu for objects
  3578. Revision 1.181 1999/12/18 14:55:21 florian
  3579. * very basic widestring support
  3580. Revision 1.180 1999/12/06 18:21:03 peter
  3581. * support !ENVVAR for long commandlines
  3582. * win32/go32v2 write short pathnames to link.res so c:\Program Files\ is
  3583. finally supported as installdir.
  3584. Revision 1.179 1999/12/01 12:42:33 peter
  3585. * fixed bug 698
  3586. * removed some notes about unused vars
  3587. Revision 1.178 1999/12/01 10:26:38 pierre
  3588. * restore the correct way for stabs of forward defs
  3589. Revision 1.177 1999/11/30 10:40:54 peter
  3590. + ttype, tsymlist
  3591. Revision 1.176 1999/11/09 23:35:49 pierre
  3592. + better reference pos for forward defs
  3593. Revision 1.175 1999/11/07 23:57:36 pierre
  3594. + higher level browser
  3595. Revision 1.174 1999/11/06 14:34:26 peter
  3596. * truncated log to 20 revs
  3597. }