symtable.pas 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. This unit handles the symbol tables
  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. unit symtable;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,symsym,
  28. { assembler }
  29. aasm
  30. ;
  31. {****************************************************************************
  32. Symtable types
  33. ****************************************************************************}
  34. type
  35. tstoredsymtable = class(tsymtable)
  36. private
  37. b_needs_init_final : boolean;
  38. procedure _needs_init_final(p : tnamedindexitem);
  39. procedure check_forward(sym : TNamedIndexItem);
  40. procedure labeldefined(p : TNamedIndexItem);
  41. procedure unitsymbolused(p : TNamedIndexItem);
  42. procedure varsymbolused(p : TNamedIndexItem);
  43. procedure TestPrivate(p : TNamedIndexItem);
  44. procedure objectprivatesymbolused(p : TNamedIndexItem);
  45. {$ifdef GDB}
  46. private
  47. asmoutput : taasmoutput;
  48. procedure concatstab(p : TNamedIndexItem);
  49. procedure resetstab(p : TNamedIndexItem);
  50. procedure concattypestab(p : TNamedIndexItem);
  51. {$endif}
  52. procedure order_overloads(p : TNamedIndexItem);
  53. procedure loaddefs;
  54. procedure loadsyms;
  55. procedure writedefs;
  56. procedure writesyms;
  57. public
  58. { load/write }
  59. procedure load;virtual;
  60. procedure write;virtual;
  61. procedure load_browser;virtual;
  62. procedure write_browser;virtual;
  63. procedure deref;virtual;
  64. procedure insert(sym : tsymentry);override;
  65. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;override;
  66. procedure allsymbolsused;
  67. procedure allprivatesused;
  68. procedure allunitsused;
  69. procedure check_forwards;
  70. procedure checklabels;
  71. function needs_init_final : boolean;
  72. { change alignment for args only parasymtable }
  73. procedure set_alignment(_alignment : longint);
  74. {$ifdef CHAINPROCSYMS}
  75. procedure chainprocsyms;
  76. {$endif CHAINPROCSYMS}
  77. procedure chainoperators;
  78. {$ifdef GDB}
  79. procedure concatstabto(asmlist : taasmoutput);virtual;
  80. function getnewtypecount : word; override;
  81. {$endif GDB}
  82. procedure testfordefaultproperty(p : TNamedIndexItem);
  83. end;
  84. tabstractrecordsymtable = class(tstoredsymtable)
  85. public
  86. procedure load;override;
  87. procedure write;override;
  88. procedure load_browser;override;
  89. procedure write_browser;override;
  90. end;
  91. trecordsymtable = class(tabstractrecordsymtable)
  92. public
  93. constructor create;
  94. procedure insert_in(tsymt : tsymtable;offset : longint);
  95. end;
  96. tobjectsymtable = class(tabstractrecordsymtable)
  97. public
  98. constructor create(const n:string);
  99. procedure insert(sym : tsymentry);override;
  100. end;
  101. tabstractlocalsymtable = class(tstoredsymtable)
  102. public
  103. procedure load;override;
  104. procedure write;override;
  105. procedure load_browser;override;
  106. procedure write_browser;override;
  107. end;
  108. tlocalsymtable = class(tabstractlocalsymtable)
  109. public
  110. constructor create;
  111. procedure insert(sym : tsymentry);override;
  112. end;
  113. tparasymtable = class(tabstractlocalsymtable)
  114. public
  115. constructor create;
  116. procedure insert(sym : tsymentry);override;
  117. end;
  118. tabstractunitsymtable = class(tstoredsymtable)
  119. public
  120. {$ifdef GDB}
  121. dbx_count : longint;
  122. prev_dbx_counter : plongint;
  123. dbx_count_ok : boolean;
  124. is_stab_written : boolean;
  125. {$endif GDB}
  126. constructor create(const n : string);
  127. {$ifdef GDB}
  128. procedure concattypestabto(asmlist : taasmoutput);
  129. {$endif GDB}
  130. end;
  131. tglobalsymtable = class(tabstractunitsymtable)
  132. private
  133. procedure writeusedmacro(p:TNamedIndexItem);
  134. public
  135. unittypecount : word;
  136. unitsym : tunitsym;
  137. constructor create(const n : string);
  138. destructor destroy;
  139. procedure load;override;
  140. procedure write;override;
  141. procedure load_symtable_refs;
  142. {$ifdef GDB}
  143. function getnewtypecount : word; override;
  144. {$endif}
  145. procedure writeusedmacros;
  146. end;
  147. tstaticsymtable = class(tabstractunitsymtable)
  148. public
  149. constructor create(const n : string);
  150. procedure load;override;
  151. procedure write;override;
  152. procedure load_browser;override;
  153. procedure write_browser;override;
  154. procedure insert(sym : tsymentry);override;
  155. end;
  156. twithsymtable = class(tsymtable)
  157. direct_with : boolean;
  158. { in fact it is a tnode }
  159. withnode : pointer;
  160. { tnode to load of direct with var }
  161. { already usable before firstwith
  162. needed for firstpass of function parameters PM }
  163. withrefnode : pointer;
  164. constructor create(aowner:tdef;asymsearch:TDictionary);
  165. destructor destroy;override;
  166. procedure clear;override;
  167. end;
  168. tstt_exceptsymtable = class(tsymtable)
  169. public
  170. constructor create;
  171. end;
  172. var
  173. constsymtable : tsymtable; { symtable were the constants can be inserted }
  174. systemunit : tglobalsymtable; { pointer to the system unit }
  175. read_member : boolean; { reading members of an symtable }
  176. lexlevel : longint; { level of code }
  177. { 1 for main procedure }
  178. { 2 for normal function or proc }
  179. { higher for locals }
  180. {****************************************************************************
  181. Functions
  182. ****************************************************************************}
  183. {*** Misc ***}
  184. procedure globaldef(const s : string;var t:ttype);
  185. function findunitsymtable(st:tsymtable):tsymtable;
  186. procedure duplicatesym(sym:tsym);
  187. procedure identifier_not_found(const s:string);
  188. {*** Search ***}
  189. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  190. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):tsym;
  191. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  192. function search_class_member(pd : tobjectdef;const s : string):tsym;
  193. {*** PPU Write/Loading ***}
  194. procedure writeunitas(const s : string;unittable : tglobalsymtable;only_crc : boolean);
  195. procedure numberunits;
  196. procedure load_interface;
  197. {*** Object Helpers ***}
  198. function search_default_property(pd : tobjectdef) : tpropertysym;
  199. {*** symtable stack ***}
  200. procedure dellexlevel;
  201. procedure RestoreUnitSyms;
  202. {$ifdef DEBUG}
  203. procedure test_symtablestack;
  204. procedure list_symtablestack;
  205. {$endif DEBUG}
  206. {$ifdef UNITALIASES}
  207. type
  208. punit_alias = ^tunit_alias;
  209. tunit_alias = object(TNamedIndexItem)
  210. newname : pstring;
  211. constructor init(const n:string);
  212. destructor done;virtual;
  213. end;
  214. var
  215. unitaliases : pdictionary;
  216. procedure addunitalias(const n:string);
  217. function getunitalias(const n:string):string;
  218. {$endif UNITALIASES}
  219. {*** Init / Done ***}
  220. procedure InitSymtable;
  221. procedure DoneSymtable;
  222. const
  223. { last operator which can be overloaded, the first_overloaded should
  224. be in tokens.pas after NOTOKEN }
  225. first_overloaded = _PLUS;
  226. last_overloaded = _ASSIGNMENT;
  227. type
  228. toverloaded_operators = array[NOTOKEN..last_overloaded] of tprocsym;
  229. var
  230. overloaded_operators : toverloaded_operators;
  231. { unequal is not equal}
  232. const
  233. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] =
  234. ('error',
  235. 'plus','minus','star','slash','equal',
  236. 'greater','lower','greater_or_equal',
  237. 'lower_or_equal',
  238. 'sym_diff','starstar',
  239. 'as','is','in','or',
  240. 'and','div','mod','not','shl','shr','xor',
  241. 'assign');
  242. implementation
  243. uses
  244. { global }
  245. version,verbose,globals,
  246. { target }
  247. systems,
  248. { ppu }
  249. symppu,ppu,
  250. { module }
  251. finput,fmodule,
  252. {$ifdef GDB}
  253. gdb,
  254. {$endif GDB}
  255. { scanner }
  256. scanner,
  257. { codegen }
  258. hcodegen
  259. ;
  260. var
  261. in_loading : boolean; { remove !!! }
  262. {*****************************************************************************
  263. TStoredSymtable
  264. *****************************************************************************}
  265. procedure tstoredsymtable.load;
  266. begin
  267. { load definitions }
  268. loaddefs;
  269. { load symbols }
  270. loadsyms;
  271. end;
  272. procedure tstoredsymtable.write;
  273. begin
  274. { write definitions }
  275. writedefs;
  276. { write symbols }
  277. writesyms;
  278. end;
  279. procedure tstoredsymtable.loaddefs;
  280. var
  281. hp : tdef;
  282. b : byte;
  283. begin
  284. { load start of definition section, which holds the amount of defs }
  285. if current_ppu^.readentry<>ibstartdefs then
  286. Message(unit_f_ppu_read_error);
  287. current_ppu^.getlongint;
  288. { read definitions }
  289. repeat
  290. b:=current_ppu^.readentry;
  291. case b of
  292. ibpointerdef : hp:=tpointerdef.load;
  293. ibarraydef : hp:=tarraydef.load;
  294. iborddef : hp:=torddef.load;
  295. ibfloatdef : hp:=tfloatdef.load;
  296. ibprocdef : hp:=tprocdef.load;
  297. ibshortstringdef : hp:=tstringdef.loadshort;
  298. iblongstringdef : hp:=tstringdef.loadlong;
  299. ibansistringdef : hp:=tstringdef.loadansi;
  300. ibwidestringdef : hp:=tstringdef.loadwide;
  301. ibrecorddef : hp:=trecorddef.load;
  302. ibobjectdef : hp:=tobjectdef.load;
  303. ibenumdef : hp:=tenumdef.load;
  304. ibsetdef : hp:=tsetdef.load;
  305. ibprocvardef : hp:=tprocvardef.load;
  306. ibfiledef : hp:=tfiledef.load;
  307. ibclassrefdef : hp:=tclassrefdef.load;
  308. ibformaldef : hp:=tformaldef.load;
  309. ibvariantdef : hp:=tvariantdef.load;
  310. ibenddefs : break;
  311. ibend : Message(unit_f_ppu_read_error);
  312. else
  313. Message1(unit_f_ppu_invalid_entry,tostr(b));
  314. end;
  315. hp.owner:=self;
  316. defindex.insert(hp);
  317. until false;
  318. end;
  319. procedure tstoredsymtable.loadsyms;
  320. var
  321. b : byte;
  322. sym : tsym;
  323. begin
  324. { load start of definition section, which holds the amount of defs }
  325. if current_ppu^.readentry<>ibstartsyms then
  326. Message(unit_f_ppu_read_error);
  327. { skip amount of symbols, not used currently }
  328. current_ppu^.getlongint;
  329. { load datasize,dataalignment of this symboltable }
  330. datasize:=current_ppu^.getlongint;
  331. dataalignment:=current_ppu^.getlongint;
  332. { now read the symbols }
  333. repeat
  334. b:=current_ppu^.readentry;
  335. case b of
  336. ibtypesym : sym:=ttypesym.load;
  337. ibprocsym : sym:=tprocsym.load;
  338. ibconstsym : sym:=tconstsym.load;
  339. ibvarsym : sym:=tvarsym.load;
  340. ibfuncretsym : sym:=tfuncretsym.load;
  341. ibabsolutesym : sym:=tabsolutesym.load;
  342. ibenumsym : sym:=tenumsym.load;
  343. ibtypedconstsym : sym:=ttypedconstsym.load;
  344. ibpropertysym : sym:=tpropertysym.load;
  345. ibunitsym : sym:=tunitsym.load;
  346. iblabelsym : sym:=tlabelsym.load;
  347. ibsyssym : sym:=tsyssym.load;
  348. ibendsyms : break;
  349. ibend : Message(unit_f_ppu_read_error);
  350. else
  351. Message1(unit_f_ppu_invalid_entry,tostr(b));
  352. end;
  353. sym.owner:=self;
  354. symindex.insert(sym);
  355. symsearch.insert(sym);
  356. until false;
  357. end;
  358. procedure tstoredsymtable.writedefs;
  359. var
  360. pd : tstoreddef;
  361. begin
  362. { each definition get a number, write then the amount of defs to the
  363. ibstartdef entry }
  364. current_ppu^.putlongint(defindex.count);
  365. current_ppu^.writeentry(ibstartdefs);
  366. { now write the definition }
  367. pd:=tstoreddef(defindex.first);
  368. while assigned(pd) do
  369. begin
  370. pd.write;
  371. pd:=tstoreddef(pd.indexnext);
  372. end;
  373. { write end of definitions }
  374. current_ppu^.writeentry(ibenddefs);
  375. end;
  376. procedure tstoredsymtable.writesyms;
  377. var
  378. pd : tstoredsym;
  379. begin
  380. { each definition get a number, write then the amount of syms and the
  381. datasize to the ibsymdef entry }
  382. current_ppu^.putlongint(symindex.count);
  383. current_ppu^.putlongint(datasize);
  384. current_ppu^.putlongint(dataalignment);
  385. current_ppu^.writeentry(ibstartsyms);
  386. { foreach is used to write all symbols }
  387. pd:=tstoredsym(symindex.first);
  388. while assigned(pd) do
  389. begin
  390. pd.write;
  391. pd:=tstoredsym(pd.indexnext);
  392. end;
  393. { end of symbols }
  394. current_ppu^.writeentry(ibendsyms);
  395. end;
  396. procedure tstoredsymtable.load_browser;
  397. var
  398. b : byte;
  399. sym : tstoredsym;
  400. prdef : tstoreddef;
  401. begin
  402. b:=current_ppu^.readentry;
  403. if b <> ibbeginsymtablebrowser then
  404. Message1(unit_f_ppu_invalid_entry,tostr(b));
  405. repeat
  406. b:=current_ppu^.readentry;
  407. case b of
  408. ibsymref :
  409. begin
  410. sym:=tstoredsym(readderef);
  411. resolvesym(tsym(sym));
  412. if assigned(sym) then
  413. sym.load_references;
  414. end;
  415. ibdefref :
  416. begin
  417. prdef:=tstoreddef(readderef);
  418. resolvedef(tdef(prdef));
  419. if assigned(prdef) then
  420. begin
  421. if prdef.deftype<>procdef then
  422. Message(unit_f_ppu_read_error);
  423. tprocdef(prdef).load_references;
  424. end;
  425. end;
  426. ibendsymtablebrowser :
  427. break;
  428. else
  429. Message1(unit_f_ppu_invalid_entry,tostr(b));
  430. end;
  431. until false;
  432. end;
  433. procedure tstoredsymtable.write_browser;
  434. var
  435. pd : tstoredsym;
  436. begin
  437. current_ppu^.writeentry(ibbeginsymtablebrowser);
  438. { foreach is used to write all symbols }
  439. pd:=tstoredsym(symindex.first);
  440. while assigned(pd) do
  441. begin
  442. pd.write_references;
  443. pd:=tstoredsym(pd.indexnext);
  444. end;
  445. current_ppu^.writeentry(ibendsymtablebrowser);
  446. end;
  447. procedure tstoredsymtable.deref;
  448. var
  449. hp : tdef;
  450. hs : tsym;
  451. begin
  452. { deref the definitions }
  453. hp:=tdef(defindex.first);
  454. while assigned(hp) do
  455. begin
  456. hp.deref;
  457. hp:=tdef(hp.indexnext);
  458. end;
  459. { first deref the ttypesyms }
  460. hs:=tsym(symindex.first);
  461. while assigned(hs) do
  462. begin
  463. hs.prederef;
  464. hs:=tsym(hs.indexnext);
  465. end;
  466. { deref the symbols }
  467. hs:=tsym(symindex.first);
  468. while assigned(hs) do
  469. begin
  470. hs.deref;
  471. hs:=tsym(hs.indexnext);
  472. end;
  473. end;
  474. procedure tstoredsymtable.insert(sym:tsymentry);
  475. var
  476. hsym : tsym;
  477. begin
  478. { set owner and sym indexnb }
  479. sym.owner:=self;
  480. {$ifdef CHAINPROCSYMS}
  481. { set the nextprocsym field }
  482. if sym.typ=procsym then
  483. chainprocsym(sym);
  484. {$endif CHAINPROCSYMS}
  485. { writes the symbol in data segment if required }
  486. { also sets the datasize of owner }
  487. if not in_loading then
  488. tstoredsym(sym).insert_in_data;
  489. { check the current symtable }
  490. hsym:=tsym(search(sym.name));
  491. if assigned(hsym) then
  492. begin
  493. { in TP and Delphi you can have a local with the
  494. same name as the function, the function is then hidden for
  495. the user. (Under delphi it can still be accessed using result),
  496. but don't allow hiding of RESULT }
  497. if (m_tp in aktmodeswitches) and
  498. (hsym.typ=funcretsym) and
  499. not((m_result in aktmodeswitches) and
  500. (hsym.name='RESULT')) then
  501. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  502. else
  503. begin
  504. DuplicateSym(hsym);
  505. exit;
  506. end;
  507. end;
  508. { register definition of typesym }
  509. if (sym.typ = typesym) and
  510. assigned(ttypesym(sym).restype.def) then
  511. begin
  512. if not(assigned(ttypesym(sym).restype.def.owner)) and
  513. (ttypesym(sym).restype.def.deftype<>errordef) then
  514. registerdef(ttypesym(sym).restype.def);
  515. {$ifdef GDB}
  516. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  517. (symtabletype in [globalsymtable,staticsymtable]) then
  518. begin
  519. ttypesym(sym).isusedinstab := true;
  520. {sym.concatstabto(debuglist);}
  521. end;
  522. {$endif GDB}
  523. end;
  524. { insert in index and search hash }
  525. symindex.insert(sym);
  526. symsearch.insert(sym);
  527. end;
  528. function tstoredsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  529. var
  530. hp : tstoredsym;
  531. newref : tref;
  532. begin
  533. hp:=tstoredsym(inherited speedsearch(s,speedvalue));
  534. if assigned(hp) then
  535. begin
  536. { reject non static members in static procedures,
  537. be carefull aktprocsym.definition is not allways
  538. loaded already (PFV) }
  539. if (symtabletype=objectsymtable) and
  540. not(sp_static in hp.symoptions) and
  541. allow_only_static
  542. {assigned(aktprocsym) and
  543. assigned(aktprocsym.definition) and
  544. ((aktprocsym.definition.options and postaticmethod)<>0)} then
  545. Message(sym_e_only_static_in_static);
  546. if (unitid<>0) and
  547. assigned(tglobalsymtable(self).unitsym) then
  548. inc(tglobalsymtable(self).unitsym.refs);
  549. {$ifdef GDB}
  550. { if it is a type, we need the stabs of this type
  551. this might be the cause of the class debug problems
  552. as TCHILDCLASS.Create did not generate appropriate
  553. stabs debug info if TCHILDCLASS wasn't used anywhere else PM }
  554. if (hp.typ=typesym) and make_ref then
  555. begin
  556. if assigned(ttypesym(hp).restype.def) then
  557. tstoreddef(ttypesym(hp).restype.def).numberstring
  558. else
  559. ttypesym(hp).isusedinstab:=true;
  560. end;
  561. {$endif GDB}
  562. { unitsym are only loaded for browsing PM }
  563. { this was buggy anyway because we could use }
  564. { unitsyms from other units in _USES !! }
  565. {if (symtabletype=unitsymtable) and (hp.typ=unitsym) and
  566. assigned(current_module) and (current_module.globalsymtable<>.load) then
  567. hp:=nil;}
  568. if assigned(hp) and
  569. (cs_browser in aktmoduleswitches) and make_ref then
  570. begin
  571. newref:=tref.create(hp.lastref,@akttokenpos);
  572. { for symbols that are in tables without
  573. browser info or syssyms (PM) }
  574. if hp.refcount=0 then
  575. begin
  576. hp.defref:=newref;
  577. hp.lastref:=newref;
  578. end
  579. else
  580. if resolving_forward and assigned(hp.defref) then
  581. { put it as second reference }
  582. begin
  583. newref.nextref:=hp.defref.nextref;
  584. hp.defref.nextref:=newref;
  585. hp.lastref.nextref:=nil;
  586. end
  587. else
  588. hp.lastref:=newref;
  589. inc(hp.refcount);
  590. end;
  591. if assigned(hp) and make_ref then
  592. begin
  593. inc(hp.refs);
  594. end;
  595. end;
  596. speedsearch:=hp;
  597. end;
  598. {**************************************
  599. Callbacks
  600. **************************************}
  601. procedure TStoredSymtable.check_forward(sym : TNamedIndexItem);
  602. begin
  603. if tsym(sym).typ=procsym then
  604. tprocsym(sym).check_forward
  605. { check also object method table }
  606. { we needn't to test the def list }
  607. { because each object has to have a type sym }
  608. else
  609. if (tsym(sym).typ=typesym) and
  610. assigned(ttypesym(sym).restype.def) and
  611. (ttypesym(sym).restype.def.deftype=objectdef) then
  612. tobjectdef(ttypesym(sym).restype.def).check_forwards;
  613. end;
  614. procedure TStoredSymtable.labeldefined(p : TNamedIndexItem);
  615. begin
  616. if (tsym(p).typ=labelsym) and
  617. not(tlabelsym(p).defined) then
  618. begin
  619. if tlabelsym(p).used then
  620. Message1(sym_e_label_used_and_not_defined,tlabelsym(p).realname)
  621. else
  622. Message1(sym_w_label_not_defined,tlabelsym(p).realname);
  623. end;
  624. end;
  625. procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem);
  626. begin
  627. if (tsym(p).typ=unitsym) and
  628. (tunitsym(p).refs=0) and
  629. { do not claim for unit name itself !! }
  630. (tunitsym(p).unitsymtable.symtabletype=globalsymtable) then
  631. MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,
  632. p.name,current_module.modulename^);
  633. end;
  634. procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem);
  635. begin
  636. if (tsym(p).typ=varsym) and
  637. ((tsym(p).owner.symtabletype in
  638. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  639. begin
  640. { unused symbol should be reported only if no }
  641. { error is reported }
  642. { if the symbol is in a register it is used }
  643. { also don't count the value parameters which have local copies }
  644. { also don't claim for high param of open parameters (PM) }
  645. if (Errorcount<>0) or
  646. (copy(p.name,1,3)='val') or
  647. (copy(p.name,1,4)='high') then
  648. exit;
  649. if (tvarsym(p).refs=0) then
  650. begin
  651. if (tsym(p).owner.symtabletype=parasymtable) or (vo_is_local_copy in tvarsym(p).varoptions) then
  652. begin
  653. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_not_used,tsym(p).realname);
  654. end
  655. else if (tsym(p).owner.symtabletype=objectsymtable) then
  656. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_not_used,tsym(p).owner.name^,tsym(p).realname)
  657. else
  658. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_not_used,tsym(p).realname);
  659. end
  660. else if tvarsym(p).varstate=vs_assigned then
  661. begin
  662. if (tsym(p).owner.symtabletype=parasymtable) then
  663. begin
  664. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  665. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname)
  666. end
  667. else if (vo_is_local_copy in tvarsym(p).varoptions) then
  668. begin
  669. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  670. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname);
  671. end
  672. else if (tsym(p).owner.symtabletype=objectsymtable) then
  673. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_only_set,tsym(p).owner.name^,tsym(p).realname)
  674. else if (tsym(p).owner.symtabletype<>parasymtable) then
  675. if not (vo_is_exported in tvarsym(p).varoptions) then
  676. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_only_set,tsym(p).realname);
  677. end;
  678. end
  679. else if ((tsym(p).owner.symtabletype in
  680. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  681. begin
  682. if (Errorcount<>0) then
  683. exit;
  684. { do not claim for inherited private fields !! }
  685. if (tstoredsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
  686. MessagePos2(tsym(p).fileinfo,sym_n_private_method_not_used,tsym(p).owner.name^,tsym(p).realname)
  687. { units references are problematic }
  688. else if (tstoredsym(p).refs=0) and not(tsym(p).typ in [funcretsym,enumsym,unitsym]) then
  689. if (tsym(p).typ<>procsym) or not (tprocsym(p).is_global) or
  690. { all program functions are declared global
  691. but unused should still be signaled PM }
  692. ((tsym(p).owner.symtabletype=staticsymtable) and
  693. not current_module.is_unit) then
  694. MessagePos2(tsym(p).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(p).typ],tsym(p).realname);
  695. end;
  696. end;
  697. procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem);
  698. begin
  699. if sp_private in tsym(p).symoptions then
  700. varsymbolused(p);
  701. end;
  702. procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem);
  703. begin
  704. {
  705. Don't test simple object aliases PM
  706. }
  707. if (tsym(p).typ=typesym) and
  708. (ttypesym(p).restype.def.deftype=objectdef) and
  709. (ttypesym(p).restype.def.typesym=tsym(p)) then
  710. tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate);
  711. end;
  712. procedure tstoredsymtable.order_overloads(p : TNamedIndexItem);
  713. begin
  714. if tsym(p).typ=procsym then
  715. tprocsym(p).order_overloaded;
  716. end;
  717. {$ifdef GDB}
  718. procedure TStoredSymtable.concatstab(p : TNamedIndexItem);
  719. begin
  720. if tsym(p).typ <> procsym then
  721. tstoredsym(p).concatstabto(asmoutput);
  722. end;
  723. procedure TStoredSymtable.resetstab(p : TNamedIndexItem);
  724. begin
  725. if tsym(p).typ <> procsym then
  726. tstoredsym(p).isstabwritten:=false;
  727. end;
  728. procedure TStoredSymtable.concattypestab(p : TNamedIndexItem);
  729. begin
  730. if tsym(p).typ = typesym then
  731. begin
  732. tstoredsym(p).isstabwritten:=false;
  733. tstoredsym(p).concatstabto(asmoutput);
  734. end;
  735. end;
  736. function tstoredsymtable.getnewtypecount : word;
  737. begin
  738. getnewtypecount:=pglobaltypecount^;
  739. inc(pglobaltypecount^);
  740. end;
  741. {$endif GDB}
  742. {$ifdef CHAINPROCSYMS}
  743. procedure chainprocsym(p : tsym);
  744. var
  745. storesymtablestack : tsymtable;
  746. srsym : tsym;
  747. srsymtable : tsymtable;
  748. begin
  749. if p.typ=procsym then
  750. begin
  751. storesymtablestack:=symtablestack;
  752. symtablestack:=p.owner.next;
  753. while assigned(symtablestack) do
  754. begin
  755. { search for same procsym in other units }
  756. searchsym(p.name,srsym,srsymtable)
  757. if assigned(srsym) and
  758. (srsym.typ=procsym) then
  759. begin
  760. tprocsym(p).nextprocsym:=tprocsym(srsym);
  761. symtablestack:=storesymtablestack;
  762. exit;
  763. end
  764. else if srsym=nil then
  765. symtablestack:=nil
  766. else
  767. symtablestack:=srsymtable.next;
  768. end;
  769. symtablestack:=storesymtablestack;
  770. end;
  771. end;
  772. {$endif}
  773. procedure tstoredsymtable.chainoperators;
  774. var
  775. p : tprocsym;
  776. t : ttoken;
  777. def : tprocdef;
  778. srsym : tsym;
  779. srsymtable,
  780. storesymtablestack : tsymtable;
  781. begin
  782. storesymtablestack:=symtablestack;
  783. symtablestack:=self;
  784. make_ref:=false;
  785. for t:=first_overloaded to last_overloaded do
  786. begin
  787. p:=nil;
  788. def:=nil;
  789. overloaded_operators[t]:=nil;
  790. { each operator has a unique lowercased internal name PM }
  791. while assigned(symtablestack) do
  792. begin
  793. searchsym(overloaded_names[t],srsym,srsymtable);
  794. if not assigned(srsym) then
  795. begin
  796. if (t=_STARSTAR) then
  797. begin
  798. symtablestack:=systemunit;
  799. searchsym('POWER',srsym,srsymtable);
  800. end;
  801. end;
  802. if assigned(srsym) then
  803. begin
  804. if (srsym.typ<>procsym) then
  805. internalerror(12344321);
  806. if assigned(p) then
  807. begin
  808. {$ifdef CHAINPROCSYMS}
  809. p.nextprocsym:=tprocsym(srsym);
  810. {$endif CHAINPROCSYMS}
  811. def.nextoverloaded:=tprocsym(srsym).definition;
  812. end
  813. else
  814. overloaded_operators[t]:=tprocsym(srsym);
  815. p:=tprocsym(srsym);
  816. def:=p.definition;
  817. while assigned(def.nextoverloaded) and
  818. (def.nextoverloaded.owner=p.owner) do
  819. def:=def.nextoverloaded;
  820. def.nextoverloaded:=nil;
  821. symtablestack:=srsym.owner.next;
  822. end
  823. else
  824. begin
  825. symtablestack:=nil;
  826. {$ifdef CHAINPROCSYMS}
  827. if assigned(p) then
  828. p.nextprocsym:=nil;
  829. {$endif CHAINPROCSYMS}
  830. end;
  831. { search for same procsym in other units }
  832. end;
  833. symtablestack:=self;
  834. end;
  835. make_ref:=true;
  836. symtablestack:=storesymtablestack;
  837. end;
  838. {***********************************************
  839. Process all entries
  840. ***********************************************}
  841. { checks, if all procsyms and methods are defined }
  842. procedure tstoredsymtable.check_forwards;
  843. begin
  844. foreach({$ifdef FPCPROCVAR}@{$endif}check_forward);
  845. end;
  846. procedure tstoredsymtable.checklabels;
  847. begin
  848. foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined);
  849. end;
  850. procedure tstoredsymtable.set_alignment(_alignment : longint);
  851. var
  852. sym : tvarsym;
  853. l : longint;
  854. begin
  855. dataalignment:=_alignment;
  856. if (symtabletype<>parasymtable) then
  857. internalerror(1111);
  858. sym:=tvarsym(symindex.first);
  859. datasize:=0;
  860. { there can be only varsyms }
  861. while assigned(sym) do
  862. begin
  863. l:=sym.getpushsize;
  864. sym.address:=datasize;
  865. datasize:=align(datasize+l,dataalignment);
  866. sym:=tvarsym(sym.indexnext);
  867. end;
  868. end;
  869. procedure tstoredsymtable.allunitsused;
  870. begin
  871. foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
  872. end;
  873. procedure tstoredsymtable.allsymbolsused;
  874. begin
  875. foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused);
  876. end;
  877. procedure tstoredsymtable.allprivatesused;
  878. begin
  879. foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused);
  880. end;
  881. {$ifdef CHAINPROCSYMS}
  882. procedure tstoredsymtable.chainprocsyms;
  883. begin
  884. foreach({$ifdef FPCPROCVAR}@{$endif}chainprocsym);
  885. end;
  886. {$endif CHAINPROCSYMS}
  887. {$ifdef GDB}
  888. procedure tstoredsymtable.concatstabto(asmlist : taasmoutput);
  889. begin
  890. asmoutput:=asmlist;
  891. if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
  892. foreach({$ifdef FPCPROCVAR}@{$endif}resetstab);
  893. foreach({$ifdef FPCPROCVAR}@{$endif}concatstab);
  894. end;
  895. {$endif}
  896. {****************************************************************************
  897. PPU Writing Helpers
  898. ****************************************************************************}
  899. procedure writesourcefiles;
  900. var
  901. hp : tinputfile;
  902. i,j : longint;
  903. begin
  904. { second write the used source files }
  905. current_ppu^.do_crc:=false;
  906. hp:=current_module.sourcefiles.files;
  907. { write source files directly in good order }
  908. j:=0;
  909. while assigned(hp) do
  910. begin
  911. inc(j);
  912. hp:=hp.ref_next;
  913. end;
  914. while j>0 do
  915. begin
  916. hp:=current_module.sourcefiles.files;
  917. for i:=1 to j-1 do
  918. hp:=hp.ref_next;
  919. current_ppu^.putstring(hp.name^);
  920. dec(j);
  921. end;
  922. current_ppu^.writeentry(ibsourcefiles);
  923. current_ppu^.do_crc:=true;
  924. end;
  925. procedure writeusedunit;
  926. var
  927. hp : tused_unit;
  928. begin
  929. numberunits;
  930. hp:=tused_unit(current_module.used_units.first);
  931. while assigned(hp) do
  932. begin
  933. { implementation units should not change
  934. the CRC PM }
  935. current_ppu^.do_crc:=hp.in_interface;
  936. current_ppu^.putstring(hp.name^);
  937. { the checksum should not affect the crc of this unit ! (PFV) }
  938. current_ppu^.do_crc:=false;
  939. current_ppu^.putlongint(hp.checksum);
  940. current_ppu^.putlongint(hp.interface_checksum);
  941. current_ppu^.putbyte(byte(hp.in_interface));
  942. current_ppu^.do_crc:=true;
  943. hp:=tused_unit(hp.next);
  944. end;
  945. current_ppu^.do_interface_crc:=true;
  946. current_ppu^.writeentry(ibloadunit);
  947. end;
  948. procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  949. var
  950. hcontainer : tlinkcontainer;
  951. s : string;
  952. mask : cardinal;
  953. begin
  954. hcontainer:=TLinkContainer.Create;
  955. while not p.empty do
  956. begin
  957. s:=p.get(mask);
  958. if strippath then
  959. current_ppu^.putstring(SplitFileName(s))
  960. else
  961. current_ppu^.putstring(s);
  962. current_ppu^.putlongint(mask);
  963. hcontainer.add(s,mask);
  964. end;
  965. current_ppu^.writeentry(id);
  966. p.Free;
  967. p:=hcontainer;
  968. end;
  969. procedure writeunitas(const s : string;unittable : tglobalsymtable;only_crc : boolean);
  970. begin
  971. Message1(unit_u_ppu_write,s);
  972. { create unit flags }
  973. with Current_Module do
  974. begin
  975. {$ifdef GDB}
  976. if cs_gdb_dbx in aktglobalswitches then
  977. flags:=flags or uf_has_dbx;
  978. {$endif GDB}
  979. if target_os.endian=endian_big then
  980. flags:=flags or uf_big_endian;
  981. if cs_browser in aktmoduleswitches then
  982. flags:=flags or uf_has_browser;
  983. if cs_local_browser in aktmoduleswitches then
  984. flags:=flags or uf_local_browser;
  985. end;
  986. {$ifdef Test_Double_checksum_write}
  987. If only_crc then
  988. Assign(CRCFile,s+'.INT')
  989. else
  990. Assign(CRCFile,s+'.IMP');
  991. Rewrite(CRCFile);
  992. {$endif def Test_Double_checksum_write}
  993. { open ppufile }
  994. current_ppu:=new(pppufile,init(s));
  995. current_ppu^.crc_only:=only_crc;
  996. if not current_ppu^.create then
  997. Message(unit_f_ppu_cannot_write);
  998. {$ifdef Test_Double_checksum}
  999. if only_crc then
  1000. begin
  1001. new(current_ppu^.crc_test);
  1002. new(current_ppu^.crc_test2);
  1003. end
  1004. else
  1005. begin
  1006. current_ppu^.crc_test:=current_module.crc_array;
  1007. current_ppu^.crc_index:=current_module.crc_size;
  1008. current_ppu^.crc_test2:=current_module.crc_array2;
  1009. current_ppu^.crc_index2:=current_module.crc_size2;
  1010. end;
  1011. {$endif def Test_Double_checksum}
  1012. current_ppu^.change_endian:=source_os.endian<>target_os.endian;
  1013. { write symbols and definitions }
  1014. unittable.write;
  1015. { flush to be sure }
  1016. current_ppu^.flush;
  1017. { create and write header }
  1018. current_ppu^.header.size:=current_ppu^.size;
  1019. current_ppu^.header.checksum:=current_ppu^.crc;
  1020. current_ppu^.header.interface_checksum:=current_ppu^.interface_crc;
  1021. current_ppu^.header.compiler:=wordversion;
  1022. current_ppu^.header.cpu:=word(target_cpu);
  1023. current_ppu^.header.target:=word(target_info.target);
  1024. current_ppu^.header.flags:=current_module.flags;
  1025. If not only_crc then
  1026. current_ppu^.writeheader;
  1027. { save crc in current_module also }
  1028. current_module.crc:=current_ppu^.crc;
  1029. current_module.interface_crc:=current_ppu^.interface_crc;
  1030. if only_crc then
  1031. begin
  1032. {$ifdef Test_Double_checksum}
  1033. current_module.crc_array:=current_ppu^.crc_test;
  1034. current_ppu^.crc_test:=nil;
  1035. current_module.crc_size:=current_ppu^.crc_index2;
  1036. current_module.crc_array2:=current_ppu^.crc_test2;
  1037. current_ppu^.crc_test2:=nil;
  1038. current_module.crc_size2:=current_ppu^.crc_index2;
  1039. {$endif def Test_Double_checksum}
  1040. closecurrentppu;
  1041. end;
  1042. {$ifdef Test_Double_checksum_write}
  1043. close(CRCFile);
  1044. {$endif Test_Double_checksum_write}
  1045. end;
  1046. procedure readusedmacros;
  1047. var
  1048. hs : string;
  1049. mac : tmacro;
  1050. was_defined_at_startup,
  1051. was_used : boolean;
  1052. begin
  1053. while not current_ppu^.endofentry do
  1054. begin
  1055. hs:=current_ppu^.getstring;
  1056. was_defined_at_startup:=boolean(current_ppu^.getbyte);
  1057. was_used:=boolean(current_ppu^.getbyte);
  1058. mac:=tmacro(current_scanner.macros.search(hs));
  1059. if assigned(mac) then
  1060. begin
  1061. {$ifndef EXTDEBUG}
  1062. { if we don't have the sources why tell }
  1063. if current_module.sources_avail then
  1064. {$endif ndef EXTDEBUG}
  1065. if (not was_defined_at_startup) and
  1066. was_used and
  1067. mac.defined_at_startup then
  1068. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module.mainsource^);
  1069. end
  1070. else { not assigned }
  1071. if was_defined_at_startup and
  1072. was_used then
  1073. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module.mainsource^);
  1074. end;
  1075. end;
  1076. procedure readsourcefiles;
  1077. var
  1078. temp,hs : string;
  1079. temp_dir : string;
  1080. main_dir : string;
  1081. incfile_found,
  1082. main_found,
  1083. is_main : boolean;
  1084. ppufiletime,
  1085. source_time : longint;
  1086. hp : tinputfile;
  1087. begin
  1088. ppufiletime:=getnamedfiletime(current_module.ppufilename^);
  1089. current_module.sources_avail:=true;
  1090. is_main:=true;
  1091. main_dir:='';
  1092. while not current_ppu^.endofentry do
  1093. begin
  1094. hs:=current_ppu^.getstring;
  1095. temp_dir:='';
  1096. if (current_module.flags and uf_in_library)<>0 then
  1097. begin
  1098. current_module.sources_avail:=false;
  1099. temp:=' library';
  1100. end
  1101. else if pos('Macro ',hs)=1 then
  1102. begin
  1103. { we don't want to find this file }
  1104. { but there is a problem with file indexing !! }
  1105. temp:='';
  1106. end
  1107. else
  1108. begin
  1109. { check the date of the source files }
  1110. Source_Time:=GetNamedFileTime(current_module.path^+hs);
  1111. incfile_found:=false;
  1112. main_found:=false;
  1113. if Source_Time<>-1 then
  1114. hs:=current_module.path^+hs
  1115. else
  1116. if not(is_main) then
  1117. begin
  1118. Source_Time:=GetNamedFileTime(main_dir+hs);
  1119. if Source_Time<>-1 then
  1120. hs:=main_dir+hs;
  1121. end;
  1122. if (Source_Time=-1) then
  1123. begin
  1124. if is_main then
  1125. main_found:=unitsearchpath.FindFile(hs,temp_dir)
  1126. else
  1127. incfile_found:=includesearchpath.FindFile(hs,temp_dir);
  1128. if incfile_found or main_found then
  1129. Source_Time:=GetNamedFileTime(temp_dir);
  1130. end;
  1131. if Source_Time=-1 then
  1132. begin
  1133. current_module.sources_avail:=false;
  1134. temp:=' not found';
  1135. end
  1136. else
  1137. begin
  1138. if main_found then
  1139. main_dir:=temp_dir;
  1140. { time newer? But only allow if the file is not searched
  1141. in the include path (PFV), else you've problems with
  1142. units which use the same includefile names }
  1143. if incfile_found then
  1144. temp:=' found'
  1145. else
  1146. begin
  1147. temp:=' time '+filetimestring(source_time);
  1148. if (source_time>ppufiletime) then
  1149. begin
  1150. current_module.do_compile:=true;
  1151. current_module.recompile_reason:=rr_sourcenewer;
  1152. temp:=temp+' *'
  1153. end;
  1154. end;
  1155. end;
  1156. hp:=tinputfile.create(hs);
  1157. { the indexing is wrong here PM }
  1158. current_module.sourcefiles.register_file(hp);
  1159. end;
  1160. if is_main then
  1161. begin
  1162. stringdispose(current_module.mainsource);
  1163. current_module.mainsource:=stringdup(hs);
  1164. end;
  1165. Message1(unit_u_ppu_source,hs+temp);
  1166. is_main:=false;
  1167. end;
  1168. { check if we want to rebuild every unit, only if the sources are
  1169. available }
  1170. if do_build and current_module.sources_avail then
  1171. begin
  1172. current_module.do_compile:=true;
  1173. current_module.recompile_reason:=rr_build;
  1174. end;
  1175. end;
  1176. procedure readloadunit;
  1177. var
  1178. hs : string;
  1179. intfchecksum,
  1180. checksum : longint;
  1181. in_interface : boolean;
  1182. begin
  1183. while not current_ppu^.endofentry do
  1184. begin
  1185. hs:=current_ppu^.getstring;
  1186. checksum:=current_ppu^.getlongint;
  1187. intfchecksum:=current_ppu^.getlongint;
  1188. in_interface:=(current_ppu^.getbyte<>0);
  1189. current_module.used_units.concat(tused_unit.create_to_load(hs,checksum,intfchecksum,in_interface));
  1190. end;
  1191. end;
  1192. procedure readlinkcontainer(var p:tlinkcontainer);
  1193. var
  1194. s : string;
  1195. m : longint;
  1196. begin
  1197. while not current_ppu^.endofentry do
  1198. begin
  1199. s:=current_ppu^.getstring;
  1200. m:=current_ppu^.getlongint;
  1201. p.add(s,m);
  1202. end;
  1203. end;
  1204. procedure load_interface;
  1205. var
  1206. b : byte;
  1207. newmodulename : string;
  1208. begin
  1209. { read interface part }
  1210. repeat
  1211. b:=current_ppu^.readentry;
  1212. case b of
  1213. ibmodulename :
  1214. begin
  1215. newmodulename:=current_ppu^.getstring;
  1216. if upper(newmodulename)<>current_module.modulename^ then
  1217. Message2(unit_f_unit_name_error,current_module.realmodulename^,newmodulename);
  1218. stringdispose(current_module.modulename);
  1219. stringdispose(current_module.realmodulename);
  1220. current_module.modulename:=stringdup(upper(newmodulename));
  1221. current_module.realmodulename:=stringdup(newmodulename);
  1222. end;
  1223. ibsourcefiles :
  1224. readsourcefiles;
  1225. ibusedmacros :
  1226. readusedmacros;
  1227. ibloadunit :
  1228. readloadunit;
  1229. iblinkunitofiles :
  1230. readlinkcontainer(current_module.LinkUnitOFiles);
  1231. iblinkunitstaticlibs :
  1232. readlinkcontainer(current_module.LinkUnitStaticLibs);
  1233. iblinkunitsharedlibs :
  1234. readlinkcontainer(current_module.LinkUnitSharedLibs);
  1235. iblinkotherofiles :
  1236. readlinkcontainer(current_module.LinkotherOFiles);
  1237. iblinkotherstaticlibs :
  1238. readlinkcontainer(current_module.LinkotherStaticLibs);
  1239. iblinkothersharedlibs :
  1240. readlinkcontainer(current_module.LinkotherSharedLibs);
  1241. ibendinterface :
  1242. break;
  1243. else
  1244. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1245. end;
  1246. until false;
  1247. end;
  1248. {****************************************************************************
  1249. TAbstractRecordSymtable
  1250. ****************************************************************************}
  1251. procedure tabstractrecordsymtable.load;
  1252. var
  1253. storesymtable : tsymtable;
  1254. begin
  1255. storesymtable:=aktrecordsymtable;
  1256. aktrecordsymtable:=self;
  1257. inherited load;
  1258. aktrecordsymtable:=storesymtable;
  1259. end;
  1260. procedure tabstractrecordsymtable.write;
  1261. var
  1262. oldtyp : byte;
  1263. storesymtable : tsymtable;
  1264. begin
  1265. storesymtable:=aktrecordsymtable;
  1266. aktrecordsymtable:=self;
  1267. oldtyp:=current_ppu^.entrytyp;
  1268. current_ppu^.entrytyp:=subentryid;
  1269. { order procsym overloads }
  1270. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1271. inherited write;
  1272. current_ppu^.entrytyp:=oldtyp;
  1273. aktrecordsymtable:=storesymtable;
  1274. end;
  1275. procedure tabstractrecordsymtable.load_browser;
  1276. var
  1277. storesymtable : tsymtable;
  1278. begin
  1279. storesymtable:=aktrecordsymtable;
  1280. aktrecordsymtable:=self;
  1281. inherited load_browser;
  1282. aktrecordsymtable:=storesymtable;
  1283. end;
  1284. procedure tabstractrecordsymtable.write_browser;
  1285. var
  1286. storesymtable : tsymtable;
  1287. begin
  1288. storesymtable:=aktrecordsymtable;
  1289. aktrecordsymtable:=self;
  1290. inherited write_browser;
  1291. aktrecordsymtable:=storesymtable;
  1292. end;
  1293. procedure TStoredSymtable._needs_init_final(p : tnamedindexitem);
  1294. begin
  1295. if (not b_needs_init_final) and
  1296. (tsym(p).typ=varsym) and
  1297. assigned(tvarsym(p).vartype.def) and
  1298. not is_class(tvarsym(p).vartype.def) and
  1299. tstoreddef(tvarsym(p).vartype.def).needs_inittable then
  1300. b_needs_init_final:=true;
  1301. end;
  1302. { returns true, if p contains data which needs init/final code }
  1303. function tstoredsymtable.needs_init_final : boolean;
  1304. begin
  1305. b_needs_init_final:=false;
  1306. foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final);
  1307. needs_init_final:=b_needs_init_final;
  1308. end;
  1309. {****************************************************************************
  1310. TRecordSymtable
  1311. ****************************************************************************}
  1312. constructor trecordsymtable.create;
  1313. begin
  1314. inherited create('');
  1315. symtabletype:=recordsymtable;
  1316. end;
  1317. { this procedure is reserved for inserting case variant into
  1318. a record symtable }
  1319. { the offset is the location of the start of the variant
  1320. and datasize and dataalignment corresponds to
  1321. the complete size (see code in pdecl unit) PM }
  1322. procedure trecordsymtable.insert_in(tsymt : tsymtable;offset : longint);
  1323. var
  1324. ps,nps : tvarsym;
  1325. pd,npd : tdef;
  1326. storesize,storealign : longint;
  1327. begin
  1328. storesize:=tsymt.datasize;
  1329. storealign:=tsymt.dataalignment;
  1330. tsymt.datasize:=offset;
  1331. ps:=tvarsym(symindex.first);
  1332. while assigned(ps) do
  1333. begin
  1334. { this is used to insert case variant into the main
  1335. record }
  1336. tsymt.datasize:=ps.address+offset;
  1337. nps:=tvarsym(ps.indexnext);
  1338. symindex.deleteindex(ps);
  1339. ps.left:=nil;
  1340. ps.right:=nil;
  1341. tsymt.insert(ps);
  1342. ps:=nps;
  1343. end;
  1344. pd:=tdef(defindex.first);
  1345. while assigned(pd) do
  1346. begin
  1347. npd:=tdef(pd.indexnext);
  1348. defindex.deleteindex(pd);
  1349. pd.left:=nil;
  1350. pd.right:=nil;
  1351. tsymt.registerdef(pd);
  1352. pd:=npd;
  1353. end;
  1354. tsymt.datasize:=storesize;
  1355. tsymt.dataalignment:=storealign;
  1356. end;
  1357. {****************************************************************************
  1358. TObjectSymtable
  1359. ****************************************************************************}
  1360. constructor tobjectsymtable.create(const n:string);
  1361. begin
  1362. inherited create(n);
  1363. symtabletype:=objectsymtable;
  1364. end;
  1365. procedure tobjectsymtable.insert(sym:tsymentry);
  1366. var
  1367. hsym : tsym;
  1368. begin
  1369. { check for duplicate field id in inherited classes }
  1370. if (sym.typ=varsym) and
  1371. assigned(defowner) and
  1372. (
  1373. not(m_delphi in aktmodeswitches) or
  1374. is_object(tdef(defowner))
  1375. ) then
  1376. begin
  1377. { but private ids can be reused }
  1378. hsym:=search_class_member(tobjectdef(defowner),sym.name);
  1379. if assigned(hsym) and
  1380. (not(sp_private in hsym.symoptions) or
  1381. (hsym.owner.defowner.owner.unitid=0)) then
  1382. begin
  1383. DuplicateSym(hsym);
  1384. exit;
  1385. end;
  1386. end;
  1387. inherited insert(sym);
  1388. end;
  1389. {****************************************************************************
  1390. TAbstractLocalSymtable
  1391. ****************************************************************************}
  1392. procedure tabstractlocalsymtable.load;
  1393. var
  1394. storesymtable : tsymtable;
  1395. begin
  1396. storesymtable:=aktlocalsymtable;
  1397. aktlocalsymtable:=self;
  1398. inherited load;
  1399. aktlocalsymtable:=storesymtable;
  1400. end;
  1401. procedure tabstractlocalsymtable.write;
  1402. var
  1403. oldtyp : byte;
  1404. storesymtable : tsymtable;
  1405. begin
  1406. storesymtable:=aktlocalsymtable;
  1407. aktlocalsymtable:=self;
  1408. oldtyp:=current_ppu^.entrytyp;
  1409. current_ppu^.entrytyp:=subentryid;
  1410. { order procsym overloads }
  1411. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1412. { write definitions }
  1413. writedefs;
  1414. { write symbols }
  1415. writesyms;
  1416. current_ppu^.entrytyp:=oldtyp;
  1417. aktlocalsymtable:=storesymtable;
  1418. end;
  1419. procedure tabstractlocalsymtable.load_browser;
  1420. var
  1421. storesymtable : tsymtable;
  1422. begin
  1423. storesymtable:=aktlocalsymtable;
  1424. aktlocalsymtable:=self;
  1425. inherited load_browser;
  1426. aktlocalsymtable:=storesymtable;
  1427. end;
  1428. procedure tabstractlocalsymtable.write_browser;
  1429. var
  1430. storesymtable : tsymtable;
  1431. begin
  1432. storesymtable:=aktlocalsymtable;
  1433. aktlocalsymtable:=self;
  1434. inherited load_browser;
  1435. aktlocalsymtable:=storesymtable;
  1436. end;
  1437. {****************************************************************************
  1438. TLocalSymtable
  1439. ****************************************************************************}
  1440. constructor tlocalsymtable.create;
  1441. begin
  1442. inherited create('');
  1443. symtabletype:=localsymtable;
  1444. end;
  1445. procedure tlocalsymtable.insert(sym:tsymentry);
  1446. var
  1447. hsym : tsym;
  1448. begin
  1449. if assigned(next) then
  1450. begin
  1451. if (next.symtabletype=parasymtable) then
  1452. begin
  1453. hsym:=tsym(next.search(sym.name));
  1454. if assigned(hsym) then
  1455. begin
  1456. { a parameter and the function can have the same
  1457. name in TP and Delphi, but RESULT not }
  1458. if (m_tp in aktmodeswitches) and
  1459. (sym.typ=funcretsym) and
  1460. not((m_result in aktmodeswitches) and
  1461. (sym.name='RESULT')) then
  1462. sym.name:='hidden'+sym.name
  1463. else
  1464. begin
  1465. DuplicateSym(hsym);
  1466. exit;
  1467. end;
  1468. end;
  1469. end
  1470. else if (current_module.flags and uf_local_browser)=0 then
  1471. internalerror(43789);
  1472. { check for duplicate id in local symtable of methods }
  1473. if assigned(next.next) and
  1474. { funcretsym is allowed !! }
  1475. (sym.typ <> funcretsym) and
  1476. (next.next.symtabletype=objectsymtable) then
  1477. begin
  1478. hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
  1479. if assigned(hsym) and
  1480. { private ids can be reused }
  1481. (not(sp_private in hsym.symoptions) or
  1482. (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
  1483. begin
  1484. { delphi allows to reuse the names in a class, but not
  1485. in object (tp7 compatible) }
  1486. if not((m_delphi in aktmodeswitches) and
  1487. is_class(tdef(next.next.defowner))) then
  1488. begin
  1489. DuplicateSym(hsym);
  1490. exit;
  1491. end;
  1492. end;
  1493. end;
  1494. end;
  1495. inherited insert(sym);
  1496. end;
  1497. {****************************************************************************
  1498. TParaSymtable
  1499. ****************************************************************************}
  1500. constructor tparasymtable.create;
  1501. begin
  1502. inherited create('');
  1503. symtabletype:=parasymtable;
  1504. dataalignment:=4;
  1505. end;
  1506. procedure tparasymtable.insert(sym:tsymentry);
  1507. var
  1508. hsym : tsym;
  1509. begin
  1510. { check for duplicate id in para symtable of methods }
  1511. if assigned(procinfo^._class) and
  1512. { but not in nested procedures !}
  1513. (not(assigned(procinfo^.parent)) or
  1514. (assigned(procinfo^.parent) and
  1515. not(assigned(procinfo^.parent^._class)))
  1516. ) and
  1517. { funcretsym is allowed !! }
  1518. (sym.typ <> funcretsym) then
  1519. begin
  1520. hsym:=search_class_member(procinfo^._class,sym.name);
  1521. if assigned(hsym) and
  1522. { private ids can be reused }
  1523. (not(sp_private in hsym.symoptions) or
  1524. (hsym.owner.defowner.owner.unitid=0)) then
  1525. begin
  1526. { delphi allows to reuse the names in a class, but not
  1527. in object (tp7 compatible) }
  1528. if not((m_delphi in aktmodeswitches) and
  1529. is_class(procinfo^._class)) then
  1530. begin
  1531. DuplicateSym(hsym);
  1532. exit;
  1533. end;
  1534. end;
  1535. end;
  1536. inherited insert(sym);
  1537. end;
  1538. {****************************************************************************
  1539. TAbstractUnitSymtable
  1540. ****************************************************************************}
  1541. constructor tabstractunitsymtable.create(const n : string);
  1542. begin
  1543. inherited create(n);
  1544. symsearch.usehash;
  1545. {$ifdef GDB}
  1546. { reset GDB things }
  1547. prev_dbx_counter := dbx_counter;
  1548. dbx_counter := nil;
  1549. is_stab_written:=false;
  1550. dbx_count := -1;
  1551. {$endif GDB}
  1552. end;
  1553. procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
  1554. var prev_dbx_count : plongint;
  1555. begin
  1556. if is_stab_written then
  1557. exit;
  1558. if not assigned(name) then
  1559. name := stringdup('Main_program');
  1560. if (symtabletype = globalsymtable) and
  1561. (current_module.globalsymtable<>self) then
  1562. begin
  1563. unitid:=current_module.unitcount;
  1564. inc(current_module.unitcount);
  1565. end;
  1566. asmList.concat(Tai_asm_comment.Create(strpnew('Begin unit '+name^+' has index '+tostr(unitid))));
  1567. if cs_gdb_dbx in aktglobalswitches then
  1568. begin
  1569. if dbx_count_ok then
  1570. begin
  1571. asmList.concat(Tai_asm_comment.Create(strpnew('"repeated" unit '+name^
  1572. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count))));
  1573. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1574. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count))));
  1575. exit;
  1576. end
  1577. else if (current_module.globalsymtable<>self) then
  1578. begin
  1579. prev_dbx_count := dbx_counter;
  1580. dbx_counter := nil;
  1581. do_count_dbx:=false;
  1582. if (symtabletype = globalsymtable) and (unitid<>0) then
  1583. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1584. dbx_counter := @dbx_count;
  1585. dbx_count:=0;
  1586. do_count_dbx:=assigned(dbx_counter);
  1587. end;
  1588. end;
  1589. asmoutput:=asmlist;
  1590. foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab);
  1591. if cs_gdb_dbx in aktglobalswitches then
  1592. begin
  1593. if (current_module.globalsymtable<>self) then
  1594. begin
  1595. dbx_counter := prev_dbx_count;
  1596. do_count_dbx:=false;
  1597. asmList.concat(Tai_asm_comment.Create(strpnew('End unit '+name^
  1598. +' has index '+tostr(unitid))));
  1599. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1600. +tostr(N_EINCL)+',0,0,0')));
  1601. do_count_dbx:=assigned(dbx_counter);
  1602. dbx_count_ok := {true}false;
  1603. end;
  1604. end;
  1605. is_stab_written:=true;
  1606. end;
  1607. {****************************************************************************
  1608. TStaticSymtable
  1609. ****************************************************************************}
  1610. constructor tstaticsymtable.create(const n : string);
  1611. begin
  1612. inherited create(n);
  1613. symtabletype:=staticsymtable;
  1614. end;
  1615. procedure tstaticsymtable.load;
  1616. begin
  1617. aktstaticsymtable:=self;
  1618. next:=symtablestack;
  1619. symtablestack:=self;
  1620. inherited load;
  1621. { now we can deref the syms and defs }
  1622. deref;
  1623. { restore symtablestack }
  1624. symtablestack:=next;
  1625. end;
  1626. procedure tstaticsymtable.write;
  1627. begin
  1628. aktstaticsymtable:=self;
  1629. { order procsym overloads }
  1630. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1631. inherited write;
  1632. end;
  1633. procedure tstaticsymtable.load_browser;
  1634. begin
  1635. aktstaticsymtable:=self;
  1636. inherited load_browser;
  1637. end;
  1638. procedure tstaticsymtable.write_browser;
  1639. begin
  1640. aktstaticsymtable:=self;
  1641. inherited write_browser;
  1642. end;
  1643. procedure tstaticsymtable.insert(sym:tsymentry);
  1644. var
  1645. hsym : tsym;
  1646. begin
  1647. { also check the global symtable }
  1648. if assigned(next) then
  1649. begin
  1650. hsym:=tsym(next.search(sym.name));
  1651. if assigned(hsym) then
  1652. begin
  1653. DuplicateSym(hsym);
  1654. exit;
  1655. end;
  1656. end;
  1657. inherited insert(sym);
  1658. end;
  1659. {****************************************************************************
  1660. TGlobalSymtable
  1661. ****************************************************************************}
  1662. constructor tglobalsymtable.create(const n : string);
  1663. begin
  1664. inherited create(n);
  1665. symtabletype:=globalsymtable;
  1666. unitid:=0;
  1667. unitsym:=nil;
  1668. {$ifdef GDB}
  1669. if cs_gdb_dbx in aktglobalswitches then
  1670. begin
  1671. dbx_count := 0;
  1672. unittypecount:=1;
  1673. pglobaltypecount := @unittypecount;
  1674. unitid:=current_module.unitcount;
  1675. debugList.concat(Tai_asm_comment.Create(strpnew('Global '+name^+' has index '+tostr(unitid))));
  1676. debugList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1677. inc(current_module.unitcount);
  1678. dbx_count_ok:=false;
  1679. dbx_counter:=@dbx_count;
  1680. do_count_dbx:=true;
  1681. end;
  1682. {$endif GDB}
  1683. end;
  1684. destructor tglobalsymtable.destroy;
  1685. var
  1686. pus : tunitsym;
  1687. begin
  1688. pus:=unitsym;
  1689. while assigned(pus) do
  1690. begin
  1691. unitsym:=pus.prevsym;
  1692. pus.prevsym:=nil;
  1693. pus.unitsymtable:=nil;
  1694. pus:=unitsym;
  1695. end;
  1696. inherited destroy;
  1697. end;
  1698. procedure tglobalsymtable.load;
  1699. var
  1700. {$ifdef GDB}
  1701. storeGlobalTypeCount : pword;
  1702. {$endif GDB}
  1703. b : byte;
  1704. begin
  1705. {$ifdef GDB}
  1706. if cs_gdb_dbx in aktglobalswitches then
  1707. begin
  1708. UnitTypeCount:=1;
  1709. storeGlobalTypeCount:=PGlobalTypeCount;
  1710. PglobalTypeCount:=@UnitTypeCount;
  1711. end;
  1712. {$endif GDB}
  1713. symtablelevel:=0;
  1714. {$ifndef NEWMAP}
  1715. current_module.map^[0]:=self;
  1716. {$else NEWMAP}
  1717. current_module.globalsymtable:=self;
  1718. {$endif NEWMAP}
  1719. next:=symtablestack;
  1720. symtablestack:=self;
  1721. inherited load;
  1722. { now we can deref the syms and defs }
  1723. deref;
  1724. { restore symtablestack }
  1725. symtablestack:=next;
  1726. {$ifdef NEWMAP}
  1727. { necessary for dependencies }
  1728. current_module.globalsymtable:=nil;
  1729. {$endif NEWMAP}
  1730. { dbx count }
  1731. {$ifdef GDB}
  1732. if (current_module.flags and uf_has_dbx)<>0 then
  1733. begin
  1734. b := current_ppu^.readentry;
  1735. if b <> ibdbxcount then
  1736. Message(unit_f_ppu_dbx_count_problem)
  1737. else
  1738. dbx_count := readlong;
  1739. dbx_count_ok := {true}false;
  1740. end
  1741. else
  1742. begin
  1743. dbx_count := -1;
  1744. dbx_count_ok:=false;
  1745. end;
  1746. if cs_gdb_dbx in aktglobalswitches then
  1747. PGlobalTypeCount:=storeGlobalTypeCount;
  1748. is_stab_written:=false;
  1749. {$endif GDB}
  1750. b:=current_ppu^.readentry;
  1751. if b<>ibendimplementation then
  1752. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1753. end;
  1754. procedure tglobalsymtable.write;
  1755. var
  1756. pu : tused_unit;
  1757. begin
  1758. { first the unitname }
  1759. current_ppu^.putstring(current_module.realmodulename^);
  1760. current_ppu^.writeentry(ibmodulename);
  1761. writesourcefiles;
  1762. writeusedmacros;
  1763. writeusedunit;
  1764. { write the objectfiles and libraries that come for this unit,
  1765. preserve the containers becuase they are still needed to load
  1766. the link.res. All doesn't depend on the crc! It doesn't matter
  1767. if a unit is in a .o or .a file }
  1768. current_ppu^.do_crc:=false;
  1769. writelinkcontainer(current_module.linkunitofiles,iblinkunitofiles,true);
  1770. writelinkcontainer(current_module.linkunitstaticlibs,iblinkunitstaticlibs,true);
  1771. writelinkcontainer(current_module.linkunitsharedlibs,iblinkunitsharedlibs,true);
  1772. writelinkcontainer(current_module.linkotherofiles,iblinkotherofiles,false);
  1773. writelinkcontainer(current_module.linkotherstaticlibs,iblinkotherstaticlibs,true);
  1774. writelinkcontainer(current_module.linkothersharedlibs,iblinkothersharedlibs,true);
  1775. current_ppu^.do_crc:=true;
  1776. current_ppu^.writeentry(ibendinterface);
  1777. { order procsym overloads }
  1778. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1779. { write the symtable entries }
  1780. inherited write;
  1781. { all after doesn't affect crc }
  1782. current_ppu^.do_crc:=false;
  1783. { write dbx count }
  1784. {$ifdef GDB}
  1785. if cs_gdb_dbx in aktglobalswitches then
  1786. begin
  1787. {$IfDef EXTDEBUG}
  1788. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1789. {$ENDIF EXTDEBUG}
  1790. current_ppu^.putlongint(dbx_count);
  1791. current_ppu^.writeentry(ibdbxcount);
  1792. end;
  1793. {$endif GDB}
  1794. current_ppu^.writeentry(ibendimplementation);
  1795. { write static symtable
  1796. needed for local debugging of unit functions }
  1797. if ((current_module.flags and uf_local_browser)<>0) and
  1798. assigned(current_module.localsymtable) then
  1799. tstaticsymtable(current_module.localsymtable).write;
  1800. { write all browser section }
  1801. if (current_module.flags and uf_has_browser)<>0 then
  1802. begin
  1803. write_browser;
  1804. pu:=tused_unit(current_module.used_units.first);
  1805. while assigned(pu) do
  1806. begin
  1807. tstoredsymtable(pu.u.globalsymtable).write_browser;
  1808. pu:=tused_unit(pu.next);
  1809. end;
  1810. current_ppu^.writeentry(ibendbrowser);
  1811. end;
  1812. if ((current_module.flags and uf_local_browser)<>0) and
  1813. assigned(current_module.localsymtable) then
  1814. tstaticsymtable(current_module.localsymtable).write_browser;
  1815. { the last entry ibend is written automaticly }
  1816. end;
  1817. procedure tglobalsymtable.load_symtable_refs;
  1818. var
  1819. b : byte;
  1820. unitindex : word;
  1821. begin
  1822. if ((current_module.flags and uf_local_browser)<>0) then
  1823. begin
  1824. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^);
  1825. tstaticsymtable(current_module.localsymtable).load;
  1826. end;
  1827. { load browser }
  1828. if (current_module.flags and uf_has_browser)<>0 then
  1829. begin
  1830. {if not (cs_browser in aktmoduleswitches) then
  1831. current_ppu^.skipuntilentry(ibendbrowser)
  1832. else }
  1833. begin
  1834. load_browser;
  1835. unitindex:=1;
  1836. while assigned(current_module.map^[unitindex]) do
  1837. begin
  1838. {each unit wrote one browser entry }
  1839. load_browser;
  1840. inc(unitindex);
  1841. end;
  1842. b:=current_ppu^.readentry;
  1843. if b<>ibendbrowser then
  1844. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1845. end;
  1846. end;
  1847. if ((current_module.flags and uf_local_browser)<>0) then
  1848. tstaticsymtable(current_module.localsymtable).load_browser;
  1849. end;
  1850. procedure tglobalsymtable.writeusedmacro(p:TNamedIndexItem);
  1851. begin
  1852. if tmacro(p).is_used or tmacro(p).defined_at_startup then
  1853. begin
  1854. current_ppu^.putstring(p.name);
  1855. current_ppu^.putbyte(byte(tmacro(p).defined_at_startup));
  1856. current_ppu^.putbyte(byte(tmacro(p).is_used));
  1857. end;
  1858. end;
  1859. procedure tglobalsymtable.writeusedmacros;
  1860. begin
  1861. current_ppu^.do_crc:=false;
  1862. current_scanner.macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro);
  1863. current_ppu^.writeentry(ibusedmacros);
  1864. current_ppu^.do_crc:=true;
  1865. end;
  1866. {$ifdef GDB}
  1867. function tglobalsymtable.getnewtypecount : word;
  1868. begin
  1869. if not (cs_gdb_dbx in aktglobalswitches) then
  1870. getnewtypecount:=inherited getnewtypecount
  1871. else
  1872. begin
  1873. getnewtypecount:=unittypecount;
  1874. inc(unittypecount);
  1875. end;
  1876. end;
  1877. {$endif}
  1878. {****************************************************************************
  1879. TWITHSYMTABLE
  1880. ****************************************************************************}
  1881. constructor twithsymtable.create(aowner:tdef;asymsearch:TDictionary);
  1882. begin
  1883. inherited create('');
  1884. symtabletype:=withsymtable;
  1885. direct_with:=false;
  1886. withnode:=nil;
  1887. withrefnode:=nil;
  1888. { we don't need the symsearch }
  1889. symsearch.free;
  1890. { set the defaults }
  1891. symsearch:=asymsearch;
  1892. defowner:=aowner;
  1893. end;
  1894. destructor twithsymtable.destroy;
  1895. begin
  1896. symsearch:=nil;
  1897. inherited destroy;
  1898. end;
  1899. procedure twithsymtable.clear;
  1900. begin
  1901. { remove no entry from a withsymtable as it is only a pointer to the
  1902. recorddef or objectdef symtable }
  1903. end;
  1904. {****************************************************************************
  1905. TSTT_ExceptionSymtable
  1906. ****************************************************************************}
  1907. constructor tstt_exceptsymtable.create;
  1908. begin
  1909. inherited create('');
  1910. symtabletype:=stt_exceptsymtable;
  1911. end;
  1912. {*****************************************************************************
  1913. Helper Routines
  1914. *****************************************************************************}
  1915. procedure numberunits;
  1916. var
  1917. counter : longint;
  1918. hp : tused_unit;
  1919. hp1 : tmodule;
  1920. begin
  1921. { Reset all numbers to -1 }
  1922. hp1:=tmodule(loaded_units.first);
  1923. while assigned(hp1) do
  1924. begin
  1925. if assigned(hp1.globalsymtable) then
  1926. tsymtable(hp1.globalsymtable).unitid:=$ffff;
  1927. hp1:=tmodule(hp1.next);
  1928. end;
  1929. { Our own symtable gets unitid 0, for a program there is
  1930. no globalsymtable }
  1931. if assigned(current_module.globalsymtable) then
  1932. tsymtable(current_module.globalsymtable).unitid:=0;
  1933. { number units }
  1934. counter:=1;
  1935. hp:=tused_unit(current_module.used_units.first);
  1936. while assigned(hp) do
  1937. begin
  1938. tsymtable(hp.u.globalsymtable).unitid:=counter;
  1939. inc(counter);
  1940. hp:=tused_unit(hp.next);
  1941. end;
  1942. end;
  1943. function findunitsymtable(st:tsymtable):tsymtable;
  1944. begin
  1945. findunitsymtable:=nil;
  1946. repeat
  1947. if not assigned(st) then
  1948. internalerror(5566561);
  1949. case st.symtabletype of
  1950. localsymtable,
  1951. parasymtable,
  1952. staticsymtable :
  1953. break;
  1954. globalsymtable :
  1955. begin
  1956. findunitsymtable:=st;
  1957. break;
  1958. end;
  1959. objectsymtable,
  1960. recordsymtable :
  1961. st:=st.defowner.owner;
  1962. else
  1963. internalerror(5566562);
  1964. end;
  1965. until false;
  1966. end;
  1967. procedure duplicatesym(sym:tsym);
  1968. var
  1969. st : tsymtable;
  1970. begin
  1971. Message1(sym_e_duplicate_id,sym.realname);
  1972. st:=findunitsymtable(sym.owner);
  1973. with sym.fileinfo do
  1974. begin
  1975. if assigned(st) and (st.unitid<>0) then
  1976. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line))
  1977. else
  1978. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line));
  1979. end;
  1980. end;
  1981. procedure identifier_not_found(const s:string);
  1982. begin
  1983. Message1(sym_e_id_not_found,s);
  1984. { show a fatal that you need -S2 or -Sd, but only
  1985. if we just parsed the a token that has m_class }
  1986. if not(m_class in aktmodeswitches) and
  1987. (Upper(s)=pattern) and
  1988. (tokeninfo^[idtoken].keyword=m_class) then
  1989. Message(parser_f_need_objfpc_or_delphi_mode);
  1990. end;
  1991. {*****************************************************************************
  1992. Search
  1993. *****************************************************************************}
  1994. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  1995. var
  1996. speedvalue : cardinal;
  1997. begin
  1998. speedvalue:=getspeedvalue(s);
  1999. srsymtable:=symtablestack;
  2000. while assigned(srsymtable) do
  2001. begin
  2002. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  2003. if assigned(srsym) then
  2004. begin
  2005. searchsym:=true;
  2006. exit;
  2007. end
  2008. else
  2009. srsymtable:=srsymtable.next;
  2010. end;
  2011. searchsym:=false;
  2012. end;
  2013. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  2014. var
  2015. srsym : tsym;
  2016. begin
  2017. { the caller have to take care if srsym=nil }
  2018. if assigned(p) then
  2019. begin
  2020. srsym:=tsym(p.search(s));
  2021. if assigned(srsym) then
  2022. begin
  2023. searchsymonlyin:=srsym;
  2024. exit;
  2025. end;
  2026. { also check in the local symtbale if it exists }
  2027. if (p=tsymtable(current_module.globalsymtable)) then
  2028. begin
  2029. srsym:=tsym(current_module.localsymtable.search(s));
  2030. if assigned(srsym) then
  2031. begin
  2032. searchsymonlyin:=srsym;
  2033. exit;
  2034. end;
  2035. end
  2036. end;
  2037. searchsymonlyin:=nil;
  2038. end;
  2039. function search_class_member(pd : tobjectdef;const s : string):tsym;
  2040. { searches n in symtable of pd and all anchestors }
  2041. var
  2042. speedvalue : cardinal;
  2043. srsym : tsym;
  2044. begin
  2045. speedvalue:=getspeedvalue(s);
  2046. while assigned(pd) do
  2047. begin
  2048. srsym:=tsym(pd.symtable.speedsearch(s,speedvalue));
  2049. if assigned(srsym) then
  2050. begin
  2051. search_class_member:=srsym;
  2052. exit;
  2053. end;
  2054. pd:=pd.childof;
  2055. end;
  2056. search_class_member:=nil;
  2057. end;
  2058. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):tsym;
  2059. {Search for a symbol in a specified symbol table. Returns nil if
  2060. the symtable is not found, and also if the symbol cannot be found
  2061. in the desired symtable }
  2062. var hsymtab:tsymtable;
  2063. res:tsym;
  2064. begin
  2065. res:=nil;
  2066. hsymtab:=symtablestack;
  2067. while (hsymtab<>nil) and (hsymtab.symtabletype<>symtabletype) do
  2068. hsymtab:=hsymtab.next;
  2069. if hsymtab<>nil then
  2070. {We found the desired symtable. Now check if the symbol we
  2071. search for is defined in it }
  2072. res:=tsym(hsymtab.search(symbol));
  2073. search_a_symtable:=res;
  2074. end;
  2075. {*****************************************************************************
  2076. Definition Helpers
  2077. *****************************************************************************}
  2078. procedure globaldef(const s : string;var t:ttype);
  2079. var st : string;
  2080. symt : tsymtable;
  2081. srsym : tsym;
  2082. srsymtable : tsymtable;
  2083. begin
  2084. srsym := nil;
  2085. if pos('.',s) > 0 then
  2086. begin
  2087. st := copy(s,1,pos('.',s)-1);
  2088. searchsym(st,srsym,srsymtable);
  2089. st := copy(s,pos('.',s)+1,255);
  2090. if assigned(srsym) then
  2091. begin
  2092. if srsym.typ = unitsym then
  2093. begin
  2094. symt := tunitsym(srsym).unitsymtable;
  2095. srsym := tsym(symt.search(st));
  2096. end else srsym := nil;
  2097. end;
  2098. end else st := s;
  2099. if srsym = nil then
  2100. searchsym(st,srsym,srsymtable);
  2101. if srsym = nil then
  2102. srsym:=searchsymonlyin(systemunit,st);
  2103. if (not assigned(srsym)) or
  2104. (srsym.typ<>typesym) then
  2105. begin
  2106. Message(type_e_type_id_expected);
  2107. t:=generrortype;
  2108. exit;
  2109. end;
  2110. t := ttypesym(srsym).restype;
  2111. end;
  2112. {****************************************************************************
  2113. Object Helpers
  2114. ****************************************************************************}
  2115. var
  2116. _defaultprop : tpropertysym;
  2117. procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem);
  2118. begin
  2119. if (tsym(p).typ=propertysym) and
  2120. (ppo_defaultproperty in tpropertysym(p).propoptions) then
  2121. _defaultprop:=tpropertysym(p);
  2122. end;
  2123. function search_default_property(pd : tobjectdef) : tpropertysym;
  2124. { returns the default property of a class, searches also anchestors }
  2125. begin
  2126. _defaultprop:=nil;
  2127. while assigned(pd) do
  2128. begin
  2129. pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty);
  2130. if assigned(_defaultprop) then
  2131. break;
  2132. pd:=pd.childof;
  2133. end;
  2134. search_default_property:=_defaultprop;
  2135. end;
  2136. {$ifdef UNITALIASES}
  2137. {****************************************************************************
  2138. TUNIT_ALIAS
  2139. ****************************************************************************}
  2140. constructor tunit_alias.create(const n:string);
  2141. var
  2142. i : longint;
  2143. begin
  2144. i:=pos('=',n);
  2145. if i=0 then
  2146. fail;
  2147. inherited createname(Copy(n,1,i-1));
  2148. newname:=stringdup(Copy(n,i+1,255));
  2149. end;
  2150. destructor tunit_alias.destroy;
  2151. begin
  2152. stringdispose(newname);
  2153. inherited destroy;
  2154. end;
  2155. procedure addunitalias(const n:string);
  2156. begin
  2157. unitaliases^.insert(tunit_alias,init(Upper(n))));
  2158. end;
  2159. function getunitalias(const n:string):string;
  2160. var
  2161. p : punit_alias;
  2162. begin
  2163. p:=punit_alias(unitaliases^.search(Upper(n)));
  2164. if assigned(p) then
  2165. getunitalias:=punit_alias(p).newname^
  2166. else
  2167. getunitalias:=n;
  2168. end;
  2169. {$endif UNITALIASES}
  2170. {****************************************************************************
  2171. Symtable Stack
  2172. ****************************************************************************}
  2173. procedure dellexlevel;
  2174. var
  2175. p : tsymtable;
  2176. begin
  2177. p:=symtablestack;
  2178. symtablestack:=p.next;
  2179. { symbol tables of unit interfaces are never disposed }
  2180. { this is handle by the unit unitm }
  2181. if not(p.symtabletype in [globalsymtable,stt_exceptsymtable]) then
  2182. p.free;
  2183. end;
  2184. procedure RestoreUnitSyms;
  2185. var
  2186. p : tsymtable;
  2187. begin
  2188. p:=symtablestack;
  2189. while assigned(p) do
  2190. begin
  2191. if (p.symtabletype=globalsymtable) and
  2192. assigned(tglobalsymtable(p).unitsym) and
  2193. ((tglobalsymtable(p).unitsym.owner=current_module.globalsymtable) or
  2194. (tglobalsymtable(p).unitsym.owner=current_module.localsymtable)) then
  2195. tglobalsymtable(p).unitsym.restoreunitsym;
  2196. p:=p.next;
  2197. end;
  2198. end;
  2199. {$ifdef DEBUG}
  2200. procedure test_symtablestack;
  2201. var
  2202. p : tsymtable;
  2203. i : longint;
  2204. begin
  2205. p:=symtablestack;
  2206. i:=0;
  2207. while assigned(p) do
  2208. begin
  2209. inc(i);
  2210. p:=p.next;
  2211. if i>500 then
  2212. Message(sym_f_internal_error_in_symtablestack);
  2213. end;
  2214. end;
  2215. procedure list_symtablestack;
  2216. var
  2217. p : tsymtable;
  2218. i : longint;
  2219. begin
  2220. p:=symtablestack;
  2221. i:=0;
  2222. while assigned(p) do
  2223. begin
  2224. inc(i);
  2225. writeln(i,' ',p.name^);
  2226. p:=p.next;
  2227. if i>500 then
  2228. Message(sym_f_internal_error_in_symtablestack);
  2229. end;
  2230. end;
  2231. {$endif DEBUG}
  2232. {****************************************************************************
  2233. Init/Done Symtable
  2234. ****************************************************************************}
  2235. procedure InitSymtable;
  2236. var
  2237. token : ttoken;
  2238. begin
  2239. { Reset symbolstack }
  2240. registerdef:=false;
  2241. read_member:=false;
  2242. symtablestack:=nil;
  2243. systemunit:=nil;
  2244. {$ifdef GDB}
  2245. firstglobaldef:=nil;
  2246. lastglobaldef:=nil;
  2247. globaltypecount:=1;
  2248. pglobaltypecount:=@globaltypecount;
  2249. {$endif GDB}
  2250. { create error syms and def }
  2251. generrorsym:=terrorsym.create;
  2252. generrortype.setdef(terrordef.create);
  2253. {$ifdef UNITALIASES}
  2254. { unit aliases }
  2255. unitaliases:=tdictionary.create;
  2256. {$endif}
  2257. for token:=first_overloaded to last_overloaded do
  2258. overloaded_operators[token]:=nil;
  2259. end;
  2260. procedure DoneSymtable;
  2261. begin
  2262. generrorsym.free;
  2263. generrortype.def.free;
  2264. {$ifdef UNITALIASES}
  2265. unitaliases.free;
  2266. {$endif}
  2267. end;
  2268. end.
  2269. {
  2270. $Log$
  2271. Revision 1.32 2001-04-13 18:08:37 peter
  2272. * scanner object to class
  2273. Revision 1.31 2001/04/13 01:22:16 peter
  2274. * symtable change to classes
  2275. * range check generation and errors fixed, make cycle DEBUG=1 works
  2276. * memory leaks fixed
  2277. Revision 1.30 2001/04/02 21:20:35 peter
  2278. * resulttype rewrite
  2279. Revision 1.29 2001/03/22 00:10:58 florian
  2280. + basic variant type support in the compiler
  2281. Revision 1.28 2001/03/13 18:45:07 peter
  2282. * fixed some memory leaks
  2283. Revision 1.27 2001/03/11 22:58:51 peter
  2284. * getsym redesign, removed the globals srsym,srsymtable
  2285. Revision 1.26 2001/02/21 19:37:19 peter
  2286. * moved deref to be done after loading of implementation units. prederef
  2287. is still done directly after loading of symbols and definitions.
  2288. Revision 1.25 2001/02/20 21:41:16 peter
  2289. * new fixfilename, findfile for unix. Look first for lowercase, then
  2290. NormalCase and last for UPPERCASE names.
  2291. Revision 1.24 2001/01/08 21:40:27 peter
  2292. * fixed crash with unsupported token overloading
  2293. Revision 1.23 2000/12/25 00:07:30 peter
  2294. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2295. tlinkedlist objects)
  2296. Revision 1.22 2000/12/23 19:50:09 peter
  2297. * fixed mem leak with withsymtable
  2298. Revision 1.21 2000/12/10 20:25:32 peter
  2299. * fixed missing typecast
  2300. Revision 1.20 2000/12/10 14:14:51 florian
  2301. * fixed web bug 1203: class fields can be now redefined
  2302. in Delphi mode though I don't like this :/
  2303. Revision 1.19 2000/11/30 22:16:49 florian
  2304. * moved to i386
  2305. Revision 1.18 2000/11/29 00:30:42 florian
  2306. * unused units removed from uses clause
  2307. * some changes for widestrings
  2308. Revision 1.17 2000/11/28 00:28:07 pierre
  2309. * stabs fixing
  2310. Revision 1.1.2.8 2000/11/17 11:14:37 pierre
  2311. * one more class stabs fix
  2312. Revision 1.16 2000/11/12 22:17:47 peter
  2313. * some realname updates for messages
  2314. Revision 1.15 2000/11/06 15:54:15 florian
  2315. * fixed two bugs to get make cycle work, but it's not enough
  2316. Revision 1.14 2000/11/04 14:25:22 florian
  2317. + merged Attila's changes for interfaces, not tested yet
  2318. Revision 1.13 2000/11/01 23:04:38 peter
  2319. * tprocdef.fullprocname added for better casesensitve writing of
  2320. procedures
  2321. Revision 1.12 2000/10/31 22:02:52 peter
  2322. * symtable splitted, no real code changes
  2323. Revision 1.1.2.7 2000/10/16 19:43:04 pierre
  2324. * trying to correct class stabss once more
  2325. Revision 1.11 2000/10/15 07:47:53 peter
  2326. * unit names and procedure names are stored mixed case
  2327. Revision 1.10 2000/10/14 10:14:53 peter
  2328. * moehrendorf oct 2000 rewrite
  2329. Revision 1.9 2000/10/01 19:48:25 peter
  2330. * lot of compile updates for cg11
  2331. Revision 1.8 2000/09/24 15:06:29 peter
  2332. * use defines.inc
  2333. Revision 1.7 2000/08/27 16:11:54 peter
  2334. * moved some util functions from globals,cobjects to cutils
  2335. * splitted files into finput,fmodule
  2336. Revision 1.6 2000/08/21 11:27:45 pierre
  2337. * fix the stabs problems
  2338. Revision 1.5 2000/08/20 14:58:41 peter
  2339. * give fatal if objfpc/delphi mode things are found (merged)
  2340. Revision 1.1.2.6 2000/08/20 14:56:46 peter
  2341. * give fatal if objfpc/delphi mode things are found
  2342. Revision 1.4 2000/08/16 18:33:54 peter
  2343. * splitted namedobjectitem.next into indexnext and listnext so it
  2344. can be used in both lists
  2345. * don't allow "word = word" type definitions (merged)
  2346. Revision 1.3 2000/08/08 19:28:57 peter
  2347. * memdebug/memory patches (merged)
  2348. * only once illegal directive (merged)
  2349. }