symdef.inc 120 KB

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