symdef.inc 121 KB

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