symtable.pas 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 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. {$ifdef TP}
  19. {$N+,E+,F+}
  20. {$endif}
  21. unit symtable;
  22. interface
  23. uses
  24. {$ifdef TP}
  25. {$ifndef Delphi}
  26. objects,
  27. {$endif Delphi}
  28. {$endif}
  29. strings,cobjects,
  30. globtype,globals,tokens,systems,verbose,
  31. symconst,
  32. aasm
  33. ,cpubase
  34. ,cpuinfo
  35. {$ifdef GDB}
  36. ,gdb
  37. {$endif}
  38. ;
  39. {************************************************
  40. Some internal constants
  41. ************************************************}
  42. const
  43. hasharraysize = 256;
  44. {$ifdef TP}
  45. indexgrowsize = 16;
  46. {$else}
  47. indexgrowsize = 64;
  48. {$endif}
  49. {************************************************
  50. Needed forward pointers
  51. ************************************************}
  52. type
  53. { needed for owner (table) of symbol }
  54. psymtable = ^tsymtable;
  55. punitsymtable = ^tunitsymtable;
  56. { needed for names by the definitions }
  57. ptypesym = ^ttypesym;
  58. penumsym = ^tenumsym;
  59. pprocsym = ^tprocsym;
  60. pref = ^tref;
  61. tref = object
  62. nextref : pref;
  63. posinfo : tfileposinfo;
  64. moduleindex : word;
  65. is_written : boolean;
  66. constructor init(ref:pref;pos:pfileposinfo);
  67. destructor done; virtual;
  68. end;
  69. { Deref entry options }
  70. tdereftype = (derefnil,derefaktrecordindex,derefaktstaticindex,
  71. derefunit,derefrecord,derefindex,
  72. dereflocal,derefpara,derefaktlocal);
  73. pderef = ^tderef;
  74. tderef = object
  75. dereftype : tdereftype;
  76. index : word;
  77. next : pderef;
  78. constructor init(typ:tdereftype;i:word);
  79. destructor done;
  80. end;
  81. psymtableentry = ^tsymtableentry;
  82. tsymtableentry = object(tnamedindexobject)
  83. owner : psymtable;
  84. end;
  85. {************************************************
  86. TDef
  87. ************************************************}
  88. {$i symdefh.inc}
  89. {************************************************
  90. TSym
  91. ************************************************}
  92. {$i symsymh.inc}
  93. {************************************************
  94. TSymtable
  95. ************************************************}
  96. tsymtabletype = (invalidsymtable,withsymtable,staticsymtable,
  97. globalsymtable,unitsymtable,
  98. objectsymtable,recordsymtable,
  99. macrosymtable,localsymtable,
  100. parasymtable,inlineparasymtable,
  101. inlinelocalsymtable,stt_exceptsymtable,
  102. { only used for PPU reading of static part
  103. of a unit }
  104. staticppusymtable);
  105. tcallback = procedure(p : psym);
  106. tsearchhasharray = array[0..hasharraysize-1] of psym;
  107. psearchhasharray = ^tsearchhasharray;
  108. tsymtable = object
  109. symtabletype : tsymtabletype;
  110. { each symtable gets a number }
  111. unitid : word{integer give range check errors PM};
  112. name : pstring;
  113. datasize : longint;
  114. dataalignment : longint;
  115. symindex,
  116. defindex : pindexarray;
  117. symsearch : pdictionary;
  118. next : psymtable;
  119. defowner : pdef; { for records and objects }
  120. { alignment used in this symtable }
  121. alignment : longint;
  122. { only used for parameter symtable to determine the offset relative }
  123. { to the frame pointer and for local inline }
  124. address_fixup : longint;
  125. { this saves all definition to allow a proper clean up }
  126. { separate lexlevel from symtable type }
  127. symtablelevel : byte;
  128. constructor init(t : tsymtabletype);
  129. destructor done;virtual;
  130. { access }
  131. function getdefnr(l : longint) : pdef;
  132. function getsymnr(l : longint) : psym;
  133. { load/write }
  134. constructor load;
  135. procedure write;
  136. constructor loadas(typ : tsymtabletype);
  137. procedure writeas;
  138. procedure loaddefs;
  139. procedure loadsyms;
  140. procedure writedefs;
  141. procedure writesyms;
  142. procedure deref;
  143. procedure clear;
  144. function rename(const olds,news : stringid):psym;
  145. procedure foreach(proc2call : tnamedindexcallback);
  146. function insert(sym : psym):psym;
  147. function search(const s : stringid) : psym;
  148. function speedsearch(const s : stringid;speedvalue : longint) : psym;
  149. procedure registerdef(p : pdef);
  150. procedure allsymbolsused;
  151. procedure allprivatesused;
  152. procedure allunitsused;
  153. procedure check_forwards;
  154. procedure checklabels;
  155. { change alignment for args only parasymtable }
  156. procedure set_alignment(_alignment : byte);
  157. { find arg having offset only parasymtable }
  158. function find_at_offset(l : longint) : pvarsym;
  159. {$ifdef CHAINPROCSYMS}
  160. procedure chainprocsyms;
  161. {$endif CHAINPROCSYMS}
  162. procedure load_browser;
  163. procedure write_browser;
  164. {$ifdef BrowserLog}
  165. procedure writebrowserlog;
  166. {$endif BrowserLog}
  167. {$ifdef GDB}
  168. procedure concatstabto(asmlist : paasmoutput);virtual;
  169. {$endif GDB}
  170. function getnewtypecount : word; virtual;
  171. end;
  172. tunitsymtable = object(tsymtable)
  173. unittypecount : word;
  174. unitsym : punitsym;
  175. {$ifdef GDB}
  176. dbx_count : longint;
  177. prev_dbx_counter : plongint;
  178. dbx_count_ok : boolean;
  179. is_stab_written : boolean;
  180. {$endif GDB}
  181. constructor init(t : tsymtabletype;const n : string);
  182. constructor loadasunit;
  183. destructor done;virtual;
  184. procedure writeasunit;
  185. {$ifdef GDB}
  186. procedure concattypestabto(asmlist : paasmoutput);
  187. {$endif GDB}
  188. procedure load_symtable_refs;
  189. function getnewtypecount : word; virtual;
  190. end;
  191. pwithsymtable = ^twithsymtable;
  192. twithsymtable = object(tsymtable)
  193. { used for withsymtable for allowing constructors }
  194. direct_with : boolean;
  195. { in fact it is a ptree }
  196. withnode : pointer;
  197. { ptree to load of direct with var }
  198. { already usable before firstwith
  199. needed for firstpass of function parameters PM }
  200. withrefnode : pointer;
  201. constructor init;
  202. destructor done;virtual;
  203. end;
  204. {****************************************************************************
  205. Var / Consts
  206. ****************************************************************************}
  207. const
  208. systemunit : punitsymtable = nil; { pointer to the system unit }
  209. current_object_option : tsymoptions = [sp_public];
  210. var
  211. { for STAB debugging }
  212. globaltypecount : word;
  213. pglobaltypecount : pword;
  214. registerdef : boolean; { true, when defs should be registered }
  215. defaultsymtablestack, { symtablestack after default units
  216. have been loaded }
  217. symtablestack : psymtable; { linked list of symtables }
  218. srsym : psym; { result of the last search }
  219. srsymtable : psymtable;
  220. lastsrsym : psym; { last sym found in statement }
  221. lastsrsymtable : psymtable;
  222. lastsymknown : boolean;
  223. constsymtable : psymtable; { symtable were the constants can be
  224. inserted }
  225. voidpointerdef : ppointerdef; { pointer for Void-Pointerdef }
  226. charpointerdef : ppointerdef; { pointer for Char-Pointerdef }
  227. voidfarpointerdef : ppointerdef;
  228. cformaldef : pformaldef; { unique formal definition }
  229. voiddef : porddef; { Pointer to Void (procedure) }
  230. cchardef : porddef; { Pointer to Char }
  231. booldef : porddef; { pointer to boolean type }
  232. u8bitdef : porddef; { Pointer to 8-Bit unsigned }
  233. u16bitdef : porddef; { Pointer to 16-Bit unsigned }
  234. u32bitdef : porddef; { Pointer to 32-Bit unsigned }
  235. s32bitdef : porddef; { Pointer to 32-Bit signed }
  236. cu64bitdef : porddef; { pointer to 64 bit unsigned def }
  237. cs64bitdef : porddef; { pointer to 64 bit signed def, }
  238. { calculated by the int unit on i386 }
  239. s32floatdef : pfloatdef; { pointer for realconstn }
  240. s64floatdef : pfloatdef; { pointer for realconstn }
  241. s80floatdef : pfloatdef; { pointer to type of temp. floats }
  242. s32fixeddef : pfloatdef; { pointer to type of temp. fixed }
  243. cshortstringdef : pstringdef; { pointer to type of short string const }
  244. clongstringdef : pstringdef; { pointer to type of long string const }
  245. cansistringdef : pstringdef; { pointer to type of ansi string const }
  246. cwidestringdef : pstringdef; { pointer to type of wide string const }
  247. openshortstringdef : pstringdef; { pointer to type of an open shortstring,
  248. needed for readln() }
  249. openchararraydef : parraydef; { pointer to type of an open array of char,
  250. needed for readln() }
  251. cfiledef : pfiledef; { get the same definition for all file }
  252. { uses for stabs }
  253. firstglobaldef, { linked list of all globals defs }
  254. lastglobaldef : pdef; { used to reset stabs/ranges }
  255. class_tobject : pobjectdef; { pointer to the anchestor of all }
  256. { clases }
  257. pvmtdef : ppointerdef; { type of classrefs }
  258. aktprocsym : pprocsym; { pointer to the symbol for the
  259. currently be parsed procedure }
  260. aktcallprocsym : pprocsym; { pointer to the symbol for the
  261. currently be called procedure,
  262. only set/unset in firstcall }
  263. aktvarsym : pvarsym; { pointer to the symbol for the
  264. currently read var, only used
  265. for variable directives }
  266. procprefix : string; { eindeutige Namen bei geschachtel- }
  267. { ten Unterprogrammen erzeugen }
  268. lexlevel : longint; { level of code }
  269. { 1 for main procedure }
  270. { 2 for normal function or proc }
  271. { higher for locals }
  272. const
  273. main_program_level = 1;
  274. unit_init_level = 1;
  275. normal_function_level = 2;
  276. in_loading : boolean = false;
  277. {$ifdef i386}
  278. bestrealdef : ^pfloatdef = @s80floatdef;
  279. {$endif}
  280. {$ifdef m68k}
  281. bestrealdef : ^pfloatdef = @s64floatdef;
  282. {$endif}
  283. {$ifdef alpha}
  284. bestrealdef : ^pfloatdef = @s64floatdef;
  285. {$endif}
  286. {$ifdef powerpc}
  287. bestrealdef : ^pfloatdef = @s64floatdef;
  288. {$endif}
  289. var
  290. macros : psymtable; { pointer for die Symboltabelle mit }
  291. { Makros }
  292. read_member : boolean; { true, wenn Members aus einer PPU- }
  293. { Datei gelesen werden, d.h. ein }
  294. { varsym seine Adresse einlesen soll }
  295. generrorsym : psym; { Jokersymbol, wenn das richtige }
  296. { Symbol nicht gefunden wird }
  297. generrordef : pdef; { Jokersymbol for eine fehlerhafte }
  298. { Typdefinition }
  299. aktobjectdef : pobjectdef; { used for private functions check !! }
  300. const
  301. { last operator which can be overloaded }
  302. first_overloaded = _PLUS;
  303. last_overloaded = _ASSIGNMENT;
  304. var
  305. overloaded_operators : array[first_overloaded..last_overloaded] of pprocsym;
  306. { unequal is not equal}
  307. const
  308. overloaded_names : array [first_overloaded..last_overloaded] of string[16] =
  309. ('plus','minus','star','slash','equal',
  310. 'greater','lower','greater_or_equal',
  311. 'lower_or_equal',
  312. 'sym_diff','starstar',
  313. 'as','is','in','or',
  314. 'and','div','mod','shl','shr','xor',
  315. 'assign');
  316. {$ifdef UNITALIASES}
  317. type
  318. punit_alias = ^tunit_alias;
  319. tunit_alias = object(tnamedindexobject)
  320. newname : pstring;
  321. constructor init(const n:string);
  322. destructor done;virtual;
  323. end;
  324. var
  325. unitaliases : pdictionary;
  326. procedure addunitalias(const n:string);
  327. function getunitalias(const n:string):string;
  328. {$endif UNITALIASES}
  329. {****************************************************************************
  330. Functions
  331. ****************************************************************************}
  332. {*** Misc ***}
  333. function globaldef(const s : string) : pdef;
  334. function findunitsymtable(st:psymtable):psymtable;
  335. procedure duplicatesym(sym:psym);
  336. {*** Search ***}
  337. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
  338. procedure getsym(const s : stringid;notfounderror : boolean);
  339. procedure getsymonlyin(p : psymtable;const s : stringid);
  340. {*** PPU Write/Loading ***}
  341. procedure writeunitas(const s : string;unittable : punitsymtable;only_crc : boolean);
  342. procedure closecurrentppu;
  343. procedure numberunits;
  344. procedure load_interface;
  345. {*** GDB ***}
  346. {$ifdef GDB}
  347. function typeglobalnumber(const s : string) : string;
  348. {$endif}
  349. {*** Definition ***}
  350. procedure reset_global_defs;
  351. {*** Object Helpers ***}
  352. function search_class_member(pd : pobjectdef;const n : string) : psym;
  353. function search_default_property(pd : pobjectdef) : ppropertysym;
  354. {*** Macro ***}
  355. procedure def_macro(const s : string);
  356. procedure set_macro(const s : string;value : string);
  357. {*** symtable stack ***}
  358. procedure dellexlevel;
  359. {$ifdef DEBUG}
  360. procedure test_symtablestack;
  361. procedure list_symtablestack;
  362. {$endif DEBUG}
  363. {*** Init / Done ***}
  364. procedure InitSymtable;
  365. procedure DoneSymtable;
  366. implementation
  367. uses
  368. version,
  369. types,ppu,
  370. gendef,files
  371. ,tree
  372. ,cresstr
  373. {$ifdef newcg}
  374. ,cgbase
  375. {$else}
  376. ,hcodegen
  377. {$endif}
  378. {$ifdef BrowserLog}
  379. ,browlog
  380. {$endif BrowserLog}
  381. {$ifdef alignreg}
  382. ,cpuasm
  383. {$endif alignreg}
  384. ;
  385. var
  386. aktrecordsymtable : psymtable; { current record read from ppu symtable }
  387. aktstaticsymtable : psymtable; { current static for local ppu symtable }
  388. aktlocalsymtable : psymtable; { current proc local for local ppu symtable }
  389. {$ifdef GDB}
  390. asmoutput : paasmoutput;
  391. {$endif GDB}
  392. {$ifdef TP}
  393. {$ifndef Delphi}
  394. {$ifndef dpmi}
  395. symbolstream : temsstream; { stream which is used to store some info }
  396. {$else}
  397. symbolstream : tmemorystream;
  398. {$endif}
  399. {$endif Delphi}
  400. {$endif}
  401. {to dispose the global symtable of a unit }
  402. const
  403. dispose_global : boolean = false;
  404. memsizeinc = 2048; { for long stabstrings }
  405. tagtypes : Set of tdeftype =
  406. [recorddef,enumdef,
  407. {$IfNDef GDBKnowsStrings}
  408. stringdef,
  409. {$EndIf not GDBKnowsStrings}
  410. {$IfNDef GDBKnowsFiles}
  411. filedef,
  412. {$EndIf not GDBKnowsFiles}
  413. objectdef];
  414. {*****************************************************************************
  415. Helper Routines
  416. *****************************************************************************}
  417. {$ifdef unused}
  418. function demangledparas(s : string) : string;
  419. var
  420. r : string;
  421. l : longint;
  422. begin
  423. demangledparas:='';
  424. r:=',';
  425. { delete leading $$'s }
  426. l:=pos('$$',s);
  427. while l<>0 do
  428. begin
  429. delete(s,1,l+1);
  430. l:=pos('$$',s);
  431. end;
  432. { delete leading _$'s }
  433. l:=pos('_$',s);
  434. while l<>0 do
  435. begin
  436. delete(s,1,l+1);
  437. l:=pos('_$',s);
  438. end;
  439. l:=pos('$',s);
  440. if l=0 then
  441. exit;
  442. delete(s,1,l);
  443. while s<>'' do
  444. begin
  445. l:=pos('$',s);
  446. if l=0 then
  447. l:=length(s)+1;
  448. r:=r+copy(s,1,l-1)+',';
  449. delete(s,1,l);
  450. end;
  451. delete(r,1,1);
  452. delete(r,length(r),1);
  453. demangledparas:=r;
  454. end;
  455. {$endif}
  456. procedure numberunits;
  457. var
  458. counter : longint;
  459. hp : pused_unit;
  460. hp1 : pmodule;
  461. begin
  462. { Reset all numbers to -1 }
  463. hp1:=pmodule(loaded_units.first);
  464. while assigned(hp1) do
  465. begin
  466. if assigned(hp1^.globalsymtable) then
  467. psymtable(hp1^.globalsymtable)^.unitid:=$ffff;
  468. hp1:=pmodule(hp1^.next);
  469. end;
  470. { Our own symtable gets unitid 0, for a program there is
  471. no globalsymtable }
  472. if assigned(current_module^.globalsymtable) then
  473. psymtable(current_module^.globalsymtable)^.unitid:=0;
  474. { number units }
  475. counter:=1;
  476. hp:=pused_unit(current_module^.used_units.first);
  477. while assigned(hp) do
  478. begin
  479. psymtable(hp^.u^.globalsymtable)^.unitid:=counter;
  480. inc(counter);
  481. hp:=pused_unit(hp^.next);
  482. end;
  483. end;
  484. function findunitsymtable(st:psymtable):psymtable;
  485. begin
  486. findunitsymtable:=nil;
  487. repeat
  488. if not assigned(st) then
  489. internalerror(5566561);
  490. case st^.symtabletype of
  491. localsymtable,
  492. parasymtable,
  493. staticsymtable :
  494. break;
  495. globalsymtable,
  496. unitsymtable :
  497. begin
  498. findunitsymtable:=st;
  499. break;
  500. end;
  501. objectsymtable,
  502. recordsymtable :
  503. st:=st^.defowner^.owner;
  504. else
  505. internalerror(5566562);
  506. end;
  507. until false;
  508. end;
  509. procedure setstring(var p : pchar;const s : string);
  510. begin
  511. {$ifndef Delphi}
  512. {$ifdef TP}
  513. if use_big then
  514. begin
  515. p:=pchar(symbolstream.getsize);
  516. symbolstream.seek(longint(p));
  517. symbolstream.writestr(@s);
  518. end
  519. else
  520. {$endif TP}
  521. {$endif Delphi}
  522. p:=strpnew(s);
  523. end;
  524. procedure duplicatesym(sym:psym);
  525. var
  526. st : psymtable;
  527. begin
  528. Message1(sym_e_duplicate_id,sym^.name);
  529. st:=findunitsymtable(sym^.owner);
  530. if assigned(st) then
  531. begin
  532. with sym^.fileinfo do
  533. begin
  534. if st^.unitid=0 then
  535. Message2(sym_h_duplicate_id_where,current_module^.sourcefiles^.get_file_name(fileindex),tostr(line))
  536. else
  537. Message2(sym_h_duplicate_id_where,'unit '+st^.name^,tostr(line));
  538. end;
  539. end;
  540. end;
  541. {****************************************************************************
  542. TRef
  543. ****************************************************************************}
  544. constructor tref.init(ref :pref;pos : pfileposinfo);
  545. begin
  546. nextref:=nil;
  547. if pos<>nil then
  548. posinfo:=pos^;
  549. if assigned(current_module) then
  550. moduleindex:=current_module^.unit_index;
  551. if assigned(ref) then
  552. ref^.nextref:=@self;
  553. is_written:=false;
  554. end;
  555. destructor tref.done;
  556. var
  557. inputfile : pinputfile;
  558. begin
  559. inputfile:=get_source_file(moduleindex,posinfo.fileindex);
  560. if inputfile<>nil then
  561. dec(inputfile^.ref_count);
  562. if assigned(nextref) then
  563. dispose(nextref,done);
  564. nextref:=nil;
  565. end;
  566. {****************************************************************************
  567. TDeref
  568. ****************************************************************************}
  569. constructor tderef.init(typ:tdereftype;i:word);
  570. begin
  571. dereftype:=typ;
  572. index:=i;
  573. next:=nil;
  574. end;
  575. destructor tderef.done;
  576. begin
  577. end;
  578. {*****************************************************************************
  579. PPU Reading Writing
  580. *****************************************************************************}
  581. {$I symppu.inc}
  582. {*****************************************************************************
  583. Definition Helpers
  584. *****************************************************************************}
  585. function globaldef(const s : string) : pdef;
  586. var st : string;
  587. symt : psymtable;
  588. begin
  589. srsym := nil;
  590. if pos('.',s) > 0 then
  591. begin
  592. st := copy(s,1,pos('.',s)-1);
  593. getsym(st,false);
  594. st := copy(s,pos('.',s)+1,255);
  595. if assigned(srsym) then
  596. begin
  597. if srsym^.typ = unitsym then
  598. begin
  599. symt := punitsym(srsym)^.unitsymtable;
  600. srsym := symt^.search(st);
  601. end else srsym := nil;
  602. end;
  603. end else st := s;
  604. if srsym = nil then getsym(st,false);
  605. if srsym = nil then
  606. getsymonlyin(systemunit,st);
  607. if srsym^.typ<>typesym then
  608. begin
  609. Message(type_e_type_id_expected);
  610. exit;
  611. end;
  612. globaldef := ptypesym(srsym)^.definition;
  613. end;
  614. {*****************************************************************************
  615. Symbol / Definition Resolving
  616. *****************************************************************************}
  617. procedure resolvederef(var p:pderef;var st:psymtable;var idx:word);
  618. var
  619. hp : pderef;
  620. pd : pdef;
  621. begin
  622. st:=nil;
  623. idx:=0;
  624. while assigned(p) do
  625. begin
  626. case p^.dereftype of
  627. derefaktrecordindex :
  628. begin
  629. st:=aktrecordsymtable;
  630. idx:=p^.index;
  631. end;
  632. derefaktstaticindex :
  633. begin
  634. st:=aktstaticsymtable;
  635. idx:=p^.index;
  636. end;
  637. derefaktlocal :
  638. begin
  639. st:=aktlocalsymtable;
  640. idx:=p^.index;
  641. end;
  642. derefunit :
  643. begin
  644. {$ifdef NEWMAP}
  645. st:=psymtable(current_module^.map^[p^.index]^.globalsymtable);
  646. {$else NEWMAP}
  647. st:=psymtable(current_module^.map^[p^.index]);
  648. {$endif NEWMAP}
  649. end;
  650. derefrecord :
  651. begin
  652. pd:=st^.getdefnr(p^.index);
  653. case pd^.deftype of
  654. recorddef :
  655. st:=precorddef(pd)^.symtable;
  656. objectdef :
  657. st:=pobjectdef(pd)^.symtable;
  658. else
  659. internalerror(556658);
  660. end;
  661. end;
  662. dereflocal :
  663. begin
  664. pd:=st^.getdefnr(p^.index);
  665. case pd^.deftype of
  666. procdef :
  667. st:=pprocdef(pd)^.localst;
  668. else
  669. internalerror(556658);
  670. end;
  671. end;
  672. derefpara :
  673. begin
  674. pd:=st^.getdefnr(p^.index);
  675. case pd^.deftype of
  676. procdef :
  677. st:=pprocdef(pd)^.parast;
  678. else
  679. internalerror(556658);
  680. end;
  681. end;
  682. derefindex :
  683. begin
  684. idx:=p^.index;
  685. end;
  686. else
  687. internalerror(556658);
  688. end;
  689. hp:=p;
  690. p:=p^.next;
  691. dispose(hp,done);
  692. end;
  693. end;
  694. procedure resolvedef(var def:pdef);
  695. var
  696. st : psymtable;
  697. idx : word;
  698. begin
  699. resolvederef(pderef(def),st,idx);
  700. if assigned(st) then
  701. def:=st^.getdefnr(idx)
  702. else
  703. def:=nil;
  704. end;
  705. procedure resolvesym(var sym:psym);
  706. var
  707. st : psymtable;
  708. idx : word;
  709. begin
  710. resolvederef(pderef(sym),st,idx);
  711. if assigned(st) then
  712. sym:=st^.getsymnr(idx)
  713. else
  714. sym:=nil;
  715. end;
  716. {*****************************************************************************
  717. Symbol Call Back Functions
  718. *****************************************************************************}
  719. procedure derefsym(p : pnamedindexobject);
  720. begin
  721. psym(p)^.deref;
  722. end;
  723. procedure derefsymsdelayed(p : pnamedindexobject);
  724. begin
  725. if psym(p)^.typ in [absolutesym,propertysym] then
  726. psym(p)^.deref;
  727. end;
  728. procedure check_forward(sym : pnamedindexobject);
  729. begin
  730. if psym(sym)^.typ=procsym then
  731. pprocsym(sym)^.check_forward
  732. { check also object method table }
  733. { we needn't to test the def list }
  734. { because each object has to have a type sym }
  735. else
  736. if (psym(sym)^.typ=typesym) and
  737. assigned(ptypesym(sym)^.definition) and
  738. (ptypesym(sym)^.definition^.deftype=objectdef) then
  739. pobjectdef(ptypesym(sym)^.definition)^.check_forwards;
  740. end;
  741. procedure labeldefined(p : pnamedindexobject);
  742. begin
  743. if (psym(p)^.typ=labelsym) and
  744. not(plabelsym(p)^.defined) then
  745. begin
  746. if plabelsym(p)^.used then
  747. Message1(sym_e_label_used_and_not_defined,p^.name)
  748. else
  749. Message1(sym_w_label_not_defined,p^.name);
  750. end;
  751. end;
  752. procedure unitsymbolused(p : pnamedindexobject);
  753. begin
  754. if (psym(p)^.typ=unitsym) and
  755. (punitsym(p)^.refs=0) then
  756. comment(V_info,'Unit '+p^.name+' is not used');
  757. end;
  758. procedure varsymbolused(p : pnamedindexobject);
  759. begin
  760. if (psym(p)^.typ=varsym) and
  761. ((psym(p)^.owner^.symtabletype in
  762. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  763. begin
  764. { unused symbol should be reported only if no }
  765. { error is reported }
  766. { if the symbol is in a register it is used }
  767. { also don't count the value parameters which have local copies }
  768. { also don't claim for high param of open parameters (PM) }
  769. if (Errorcount<>0) or
  770. (copy(p^.name,1,3)='val') or
  771. (copy(p^.name,1,4)='high') then
  772. exit;
  773. if (pvarsym(p)^.refs=0) then
  774. begin
  775. if (psym(p)^.owner^.symtabletype=parasymtable) or pvarsym(p)^.islocalcopy then
  776. begin
  777. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_not_used,p^.name);
  778. end
  779. else if (psym(p)^.owner^.symtabletype=objectsymtable) then
  780. MessagePos2(psym(p)^.fileinfo,sym_n_private_identifier_not_used,psym(p)^.owner^.name^,p^.name)
  781. else
  782. MessagePos1(psym(p)^.fileinfo,sym_n_local_identifier_not_used,p^.name);
  783. end
  784. else if pvarsym(p)^.varstate=vs_assigned then
  785. begin
  786. if (psym(p)^.owner^.symtabletype=parasymtable) then
  787. begin
  788. if (pvarsym(p)^.varspez<>vs_var) then
  789. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name)
  790. end
  791. else if pvarsym(p)^.islocalcopy then
  792. begin
  793. if (pvarsym(p)^.varspez<>vs_var) then
  794. MessagePos1(psym(p)^.fileinfo,sym_h_para_identifier_only_set,p^.name);
  795. end
  796. else if (psym(p)^.owner^.symtabletype=objectsymtable) then
  797. MessagePos2(psym(p)^.fileinfo,sym_n_private_identifier_only_set,psym(p)^.owner^.name^,p^.name)
  798. else if (psym(p)^.owner^.symtabletype<>parasymtable) then
  799. MessagePos1(psym(p)^.fileinfo,sym_n_local_identifier_only_set,p^.name);
  800. end;
  801. end
  802. else if ((psym(p)^.owner^.symtabletype in
  803. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  804. begin
  805. if (Errorcount<>0) then
  806. exit;
  807. if (psym(p)^.refs=0) and (psym(p)^.owner^.symtabletype=objectsymtable) then
  808. MessagePos2(psym(p)^.fileinfo,sym_n_private_method_not_used,psym(p)^.owner^.name^,p^.name)
  809. { units references are problematic }
  810. else if (psym(p)^.refs=0) and not(psym(p)^.typ in [funcretsym,enumsym,unitsym]) then
  811. if (psym(p)^.typ<>procsym) or not (pprocsym(p)^.is_global) or
  812. { all program functions are declared global
  813. but unused should still be signaled PM }
  814. ((psym(p)^.owner^.symtabletype=staticsymtable) and
  815. not current_module^.is_unit) then
  816. MessagePos2(psym(p)^.fileinfo,sym_h_local_symbol_not_used,SymTypeName[psym(p)^.typ],p^.name);
  817. end;
  818. end;
  819. procedure TestPrivate(p : pnamedindexobject);
  820. begin
  821. if sp_private in psym(p)^.symoptions then
  822. varsymbolused(p);
  823. end;
  824. procedure objectprivatesymbolused(p : pnamedindexobject);
  825. begin
  826. if (psym(p)^.typ=typesym) and
  827. (ptypesym(p)^.definition^.deftype=objectdef) then
  828. pobjectdef(ptypesym(p)^.definition)^.symtable^.foreach(
  829. {$ifndef TP}@{$endif}TestPrivate);
  830. end;
  831. {$ifdef GDB}
  832. procedure concatstab(p : pnamedindexobject);
  833. begin
  834. if psym(p)^.typ <> procsym then
  835. psym(p)^.concatstabto(asmoutput);
  836. end;
  837. procedure concattypestab(p : pnamedindexobject);
  838. begin
  839. if psym(p)^.typ = typesym then
  840. begin
  841. psym(p)^.isstabwritten:=false;
  842. psym(p)^.concatstabto(asmoutput);
  843. end;
  844. end;
  845. procedure forcestabto(asmlist : paasmoutput; pd : pdef);
  846. begin
  847. if not pd^.is_def_stab_written then
  848. begin
  849. if assigned(pd^.sym) then
  850. pd^.sym^.isusedinstab := true;
  851. pd^.concatstabto(asmlist);
  852. end;
  853. end;
  854. {$endif}
  855. {$ifdef CHAINPROCSYMS}
  856. procedure chainprocsym(p : psym);
  857. var
  858. storesymtablestack : psymtable;
  859. begin
  860. if p^.typ=procsym then
  861. begin
  862. storesymtablestack:=symtablestack;
  863. symtablestack:=p^.owner^.next;
  864. while assigned(symtablestack) do
  865. begin
  866. { search for same procsym in other units }
  867. getsym(p^.name,false);
  868. if assigned(srsym) and (srsym^.typ=procsym) then
  869. begin
  870. pprocsym(p)^.nextprocsym:=pprocsym(srsym);
  871. symtablestack:=storesymtablestack;
  872. exit;
  873. end
  874. else if srsym=nil then
  875. symtablestack:=nil
  876. else
  877. symtablestack:=srsymtable^.next;
  878. end;
  879. symtablestack:=storesymtablestack;
  880. end;
  881. end;
  882. {$endif}
  883. procedure write_refs(sym : pnamedindexobject);
  884. begin
  885. psym(sym)^.write_references;
  886. end;
  887. {$ifdef BrowserLog}
  888. procedure add_to_browserlog(sym : pnamedindexobject);
  889. begin
  890. psym(sym)^.add_to_browserlog;
  891. end;
  892. {$endif UseBrowser}
  893. {*****************************************************************************
  894. Search Symtables for Syms
  895. *****************************************************************************}
  896. procedure getsym(const s : stringid;notfounderror : boolean);
  897. var
  898. speedvalue : longint;
  899. begin
  900. speedvalue:=getspeedvalue(s);
  901. lastsrsym:=nil;
  902. srsymtable:=symtablestack;
  903. while assigned(srsymtable) do
  904. begin
  905. srsym:=srsymtable^.speedsearch(s,speedvalue);
  906. if assigned(srsym) then
  907. exit
  908. else
  909. srsymtable:=srsymtable^.next;
  910. end;
  911. if notfounderror then
  912. begin
  913. Message1(sym_e_id_not_found,s);
  914. srsym:=generrorsym;
  915. end
  916. else
  917. srsym:=nil;
  918. end;
  919. procedure getsymonlyin(p : psymtable;const s : stringid);
  920. begin
  921. { the caller have to take care if srsym=nil (FK) }
  922. srsym:=nil;
  923. if assigned(p) then
  924. begin
  925. srsymtable:=p;
  926. srsym:=srsymtable^.search(s);
  927. if assigned(srsym) then
  928. exit
  929. else
  930. begin
  931. if (punitsymtable(srsymtable)=punitsymtable(current_module^.globalsymtable)) then
  932. begin
  933. getsymonlyin(psymtable(current_module^.localsymtable),s);
  934. if assigned(srsym) then
  935. srsymtable:=psymtable(current_module^.localsymtable)
  936. else
  937. Message1(sym_e_id_not_found,s);
  938. end
  939. else
  940. Message1(sym_e_id_not_found,s);
  941. end;
  942. end;
  943. end;
  944. function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
  945. {Search for a symbol in a specified symbol table. Returns nil if
  946. the symtable is not found, and also if the symbol cannot be found
  947. in the desired symtable }
  948. var hsymtab:Psymtable;
  949. res:Psym;
  950. begin
  951. res:=nil;
  952. hsymtab:=symtablestack;
  953. while (hsymtab<>nil) and (hsymtab^.symtabletype<>symtabletype) do
  954. hsymtab:=hsymtab^.next;
  955. if hsymtab<>nil then
  956. {We found the desired symtable. Now check if the symbol we
  957. search for is defined in it }
  958. res:=hsymtab^.search(symbol);
  959. search_a_symtable:=res;
  960. end;
  961. {****************************************************************************
  962. TSYMTABLE
  963. ****************************************************************************}
  964. constructor tsymtable.init(t : tsymtabletype);
  965. begin
  966. symtabletype:=t;
  967. symtablelevel:=0;
  968. defowner:=nil;
  969. unitid:=0;
  970. next:=nil;
  971. name:=nil;
  972. address_fixup:=0;
  973. datasize:=0;
  974. dataalignment:=1;
  975. new(symindex,init(indexgrowsize));
  976. new(defindex,init(indexgrowsize));
  977. if symtabletype<>withsymtable then
  978. begin
  979. new(symsearch,init);
  980. symsearch^.noclear:=true;
  981. end
  982. else
  983. symsearch:=nil;
  984. alignment:=def_alignment;
  985. end;
  986. destructor tsymtable.done;
  987. begin
  988. stringdispose(name);
  989. dispose(symindex,done);
  990. dispose(defindex,done);
  991. { symsearch can already be disposed or set to nil for withsymtable }
  992. if assigned(symsearch) then
  993. begin
  994. dispose(symsearch,done);
  995. symsearch:=nil;
  996. end;
  997. end;
  998. constructor twithsymtable.init;
  999. begin
  1000. inherited init(withsymtable);
  1001. direct_with:=false;
  1002. withnode:=nil;
  1003. withrefnode:=nil;
  1004. end;
  1005. destructor twithsymtable.done;
  1006. begin
  1007. symsearch:=nil;
  1008. inherited done;
  1009. end;
  1010. {***********************************************
  1011. Helpers
  1012. ***********************************************}
  1013. function tsymtable.getnewtypecount : word;
  1014. begin
  1015. getnewtypecount:=pglobaltypecount^;
  1016. inc(pglobaltypecount^);
  1017. end;
  1018. procedure tsymtable.registerdef(p : pdef);
  1019. begin
  1020. defindex^.insert(p);
  1021. { set def owner and indexnb }
  1022. p^.owner:=@self;
  1023. end;
  1024. procedure order_overloads(p : Pnamedindexobject);
  1025. begin
  1026. if psym(p)^.typ=procsym then
  1027. pprocsym(p)^.order_overloaded;
  1028. end;
  1029. procedure tsymtable.foreach(proc2call : tnamedindexcallback);
  1030. begin
  1031. symindex^.foreach(proc2call);
  1032. end;
  1033. {***********************************************
  1034. LOAD / WRITE SYMTABLE FROM PPU
  1035. ***********************************************}
  1036. procedure tsymtable.loaddefs;
  1037. var
  1038. hp : pdef;
  1039. b : byte;
  1040. begin
  1041. { load start of definition section, which holds the amount of defs }
  1042. if current_ppu^.readentry<>ibstartdefs then
  1043. Message(unit_f_ppu_read_error);
  1044. current_ppu^.getlongint;
  1045. { read definitions }
  1046. repeat
  1047. b:=current_ppu^.readentry;
  1048. case b of
  1049. ibpointerdef : hp:=new(ppointerdef,load);
  1050. ibarraydef : hp:=new(parraydef,load);
  1051. iborddef : hp:=new(porddef,load);
  1052. ibfloatdef : hp:=new(pfloatdef,load);
  1053. ibprocdef : hp:=new(pprocdef,load);
  1054. ibshortstringdef : hp:=new(pstringdef,shortload);
  1055. iblongstringdef : hp:=new(pstringdef,longload);
  1056. ibansistringdef : hp:=new(pstringdef,ansiload);
  1057. ibwidestringdef : hp:=new(pstringdef,wideload);
  1058. ibrecorddef : hp:=new(precorddef,load);
  1059. ibobjectdef : hp:=new(pobjectdef,load);
  1060. ibenumdef : hp:=new(penumdef,load);
  1061. ibsetdef : hp:=new(psetdef,load);
  1062. ibprocvardef : hp:=new(pprocvardef,load);
  1063. ibfiledef : hp:=new(pfiledef,load);
  1064. ibclassrefdef : hp:=new(pclassrefdef,load);
  1065. ibformaldef : hp:=new(pformaldef,load);
  1066. ibenddefs : break;
  1067. ibend : Message(unit_f_ppu_read_error);
  1068. else
  1069. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1070. end;
  1071. hp^.owner:=@self;
  1072. defindex^.insert(hp);
  1073. until false;
  1074. end;
  1075. procedure tsymtable.loadsyms;
  1076. var
  1077. b : byte;
  1078. sym : psym;
  1079. begin
  1080. { load start of definition section, which holds the amount of defs }
  1081. if current_ppu^.readentry<>ibstartsyms then
  1082. Message(unit_f_ppu_read_error);
  1083. { skip amount of symbols, not used currently }
  1084. current_ppu^.getlongint;
  1085. { load datasize,dataalignment of this symboltable }
  1086. datasize:=current_ppu^.getlongint;
  1087. dataalignment:=current_ppu^.getlongint;
  1088. { now read the symbols }
  1089. repeat
  1090. b:=current_ppu^.readentry;
  1091. case b of
  1092. ibtypesym : sym:=new(ptypesym,load);
  1093. ibprocsym : sym:=new(pprocsym,load);
  1094. ibconstsym : sym:=new(pconstsym,load);
  1095. ibvarsym : sym:=new(pvarsym,load);
  1096. ibfuncretsym : sym:=new(pfuncretsym,load);
  1097. ibabsolutesym : sym:=new(pabsolutesym,load);
  1098. ibenumsym : sym:=new(penumsym,load);
  1099. ibtypedconstsym : sym:=new(ptypedconstsym,load);
  1100. ibpropertysym : sym:=new(ppropertysym,load);
  1101. ibunitsym : sym:=new(punitsym,load);
  1102. iblabelsym : sym:=new(plabelsym,load);
  1103. ibsyssym : sym:=new(psyssym,load);
  1104. ibendsyms : break;
  1105. ibend : Message(unit_f_ppu_read_error);
  1106. else
  1107. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1108. end;
  1109. sym^.owner:=@self;
  1110. symindex^.insert(sym);
  1111. symsearch^.insert(sym);
  1112. until false;
  1113. end;
  1114. procedure tsymtable.writedefs;
  1115. var
  1116. pd : pdef;
  1117. begin
  1118. { each definition get a number, write then the amount of defs to the
  1119. ibstartdef entry }
  1120. current_ppu^.putlongint(defindex^.count);
  1121. current_ppu^.writeentry(ibstartdefs);
  1122. { now write the definition }
  1123. pd:=pdef(defindex^.first);
  1124. while assigned(pd) do
  1125. begin
  1126. pd^.write;
  1127. pd:=pdef(pd^.next);
  1128. end;
  1129. { write end of definitions }
  1130. current_ppu^.writeentry(ibenddefs);
  1131. end;
  1132. procedure tsymtable.writesyms;
  1133. var
  1134. pd : psym;
  1135. begin
  1136. { each definition get a number, write then the amount of syms and the
  1137. datasize to the ibsymdef entry }
  1138. current_ppu^.putlongint(symindex^.count);
  1139. current_ppu^.putlongint(datasize);
  1140. current_ppu^.putlongint(dataalignment);
  1141. current_ppu^.writeentry(ibstartsyms);
  1142. { foreach is used to write all symbols }
  1143. pd:=psym(symindex^.first);
  1144. while assigned(pd) do
  1145. begin
  1146. pd^.write;
  1147. pd:=psym(pd^.next);
  1148. end;
  1149. { end of symbols }
  1150. current_ppu^.writeentry(ibendsyms);
  1151. end;
  1152. procedure tsymtable.deref;
  1153. var
  1154. hp : pdef;
  1155. hs : psym;
  1156. begin
  1157. hp:=pdef(defindex^.first);
  1158. while assigned(hp) do
  1159. begin
  1160. hp^.deref;
  1161. hp^.symderef;
  1162. hp:=pdef(hp^.next);
  1163. end;
  1164. hs:=psym(symindex^.first);
  1165. while assigned(hs) do
  1166. begin
  1167. hs^.deref;
  1168. hs:=psym(hs^.next);
  1169. end;
  1170. end;
  1171. constructor tsymtable.load;
  1172. var
  1173. st_loading : boolean;
  1174. begin
  1175. st_loading:=in_loading;
  1176. in_loading:=true;
  1177. {$ifndef NEWMAP}
  1178. current_module^.map^[0]:=@self;
  1179. {$else NEWMAP}
  1180. current_module^.globalsymtable:=@self;
  1181. {$endif NEWMAP}
  1182. symtabletype:=unitsymtable;
  1183. symtablelevel:=0;
  1184. { unused for units }
  1185. address_fixup:=0;
  1186. datasize:=0;
  1187. defowner:=nil;
  1188. name:=nil;
  1189. unitid:=0;
  1190. defowner:=nil;
  1191. new(symindex,init(indexgrowsize));
  1192. new(defindex,init(indexgrowsize));
  1193. new(symsearch,init);
  1194. symsearch^.usehash;
  1195. symsearch^.noclear:=true;
  1196. alignment:=def_alignment;
  1197. { load definitions }
  1198. loaddefs;
  1199. { load symbols }
  1200. loadsyms;
  1201. { Now we can deref the symbols and definitions }
  1202. if not(symtabletype in [objectsymtable,recordsymtable]) then
  1203. deref;
  1204. {$ifdef NEWMAP}
  1205. { necessary for dependencies }
  1206. current_module^.globalsymtable:=nil;
  1207. {$endif NEWMAP}
  1208. in_loading:=st_loading;
  1209. end;
  1210. procedure tsymtable.write;
  1211. begin
  1212. { write definitions }
  1213. foreach({$ifndef TP}@{$endif}Order_overloads);
  1214. writedefs;
  1215. { write symbols }
  1216. writesyms;
  1217. end;
  1218. constructor tsymtable.loadas(typ : tsymtabletype);
  1219. var
  1220. storesymtable : psymtable;
  1221. st_loading : boolean;
  1222. begin
  1223. st_loading:=in_loading;
  1224. in_loading:=true;
  1225. symtabletype:=typ;
  1226. new(symindex,init(indexgrowsize));
  1227. new(defindex,init(indexgrowsize));
  1228. new(symsearch,init);
  1229. symsearch^.noclear:=true;
  1230. defowner:=nil;
  1231. if typ in [recordsymtable,objectsymtable] then
  1232. begin
  1233. storesymtable:=aktrecordsymtable;
  1234. aktrecordsymtable:=@self;
  1235. end;
  1236. if typ in [parasymtable,localsymtable] then
  1237. begin
  1238. storesymtable:=aktlocalsymtable;
  1239. aktlocalsymtable:=@self;
  1240. end;
  1241. { used for local browser }
  1242. if typ=staticppusymtable then
  1243. begin
  1244. aktstaticsymtable:=@self;
  1245. symsearch^.usehash;
  1246. end;
  1247. name:=nil;
  1248. alignment:=def_alignment;
  1249. { isn't used there }
  1250. datasize:=0;
  1251. address_fixup:= 0;
  1252. { also unused }
  1253. unitid:=0;
  1254. { load definitions }
  1255. { we need the correct symtable for registering }
  1256. if not (typ in [localsymtable,parasymtable,recordsymtable,objectsymtable]) then
  1257. begin
  1258. next:=symtablestack;
  1259. symtablestack:=@self;
  1260. end;
  1261. { load definitions }
  1262. loaddefs;
  1263. { load symbols }
  1264. loadsyms;
  1265. { now we can deref the syms and defs }
  1266. if not (typ in [localsymtable,parasymtable,
  1267. recordsymtable,objectsymtable]) then
  1268. deref;
  1269. if typ in [recordsymtable,objectsymtable] then
  1270. aktrecordsymtable:=storesymtable;
  1271. if typ in [localsymtable,parasymtable] then
  1272. aktlocalsymtable:=storesymtable;
  1273. if not (typ in [localsymtable,parasymtable,recordsymtable,objectsymtable]) then
  1274. begin
  1275. symtablestack:=next;
  1276. end;
  1277. in_loading:=st_loading;
  1278. end;
  1279. procedure tsymtable.writeas;
  1280. var
  1281. oldtyp : byte;
  1282. storesymtable : psymtable;
  1283. begin
  1284. oldtyp:=current_ppu^.entrytyp;
  1285. storesymtable:=aktrecordsymtable;
  1286. if symtabletype in [recordsymtable,objectsymtable] then
  1287. begin
  1288. storesymtable:=aktrecordsymtable;
  1289. aktrecordsymtable:=@self;
  1290. end;
  1291. if symtabletype in [parasymtable,localsymtable] then
  1292. begin
  1293. storesymtable:=aktlocalsymtable;
  1294. aktlocalsymtable:=@self;
  1295. end;
  1296. if (symtabletype in [recordsymtable,objectsymtable]) then
  1297. current_ppu^.entrytyp:=subentryid;
  1298. { order procsym overloads }
  1299. foreach({$ifndef TP}@{$endif}Order_overloads);
  1300. { write definitions }
  1301. writedefs;
  1302. { write symbols }
  1303. writesyms;
  1304. current_ppu^.entrytyp:=oldtyp;
  1305. if symtabletype in [recordsymtable,objectsymtable] then
  1306. aktrecordsymtable:=storesymtable;
  1307. if symtabletype in [localsymtable,parasymtable] then
  1308. aktlocalsymtable:=storesymtable;
  1309. end;
  1310. {***********************************************
  1311. Get Symbol / Def by Number
  1312. ***********************************************}
  1313. function tsymtable.getsymnr(l : longint) : psym;
  1314. var
  1315. hp : psym;
  1316. begin
  1317. hp:=psym(symindex^.search(l));
  1318. if hp=nil then
  1319. internalerror(10999);
  1320. getsymnr:=hp;
  1321. end;
  1322. function tsymtable.getdefnr(l : longint) : pdef;
  1323. var
  1324. hp : pdef;
  1325. begin
  1326. hp:=pdef(defindex^.search(l));
  1327. if hp=nil then
  1328. internalerror(10998);
  1329. getdefnr:=hp;
  1330. end;
  1331. {***********************************************
  1332. Table Access
  1333. ***********************************************}
  1334. procedure tsymtable.clear;
  1335. begin
  1336. { remove no entry from a withsymtable as it is only a pointer to the
  1337. recorddef or objectdef symtable }
  1338. if symtabletype=withsymtable then
  1339. exit;
  1340. symindex^.clear;
  1341. defindex^.clear;
  1342. end;
  1343. function tsymtable.insert(sym:psym):psym;
  1344. var
  1345. hp : psymtable;
  1346. hsym : psym;
  1347. begin
  1348. { set owner and sym indexnb }
  1349. sym^.owner:=@self;
  1350. {$ifdef CHAINPROCSYMS}
  1351. { set the nextprocsym field }
  1352. if sym^.typ=procsym then
  1353. chainprocsym(sym);
  1354. {$endif CHAINPROCSYMS}
  1355. { writes the symbol in data segment if required }
  1356. { also sets the datasize of owner }
  1357. if not in_loading then
  1358. sym^.insert_in_data;
  1359. if (symtabletype in [staticsymtable,globalsymtable]) then
  1360. begin
  1361. hp:=symtablestack;
  1362. while assigned(hp) do
  1363. begin
  1364. if hp^.symtabletype in [staticsymtable,globalsymtable] then
  1365. begin
  1366. hsym:=hp^.search(sym^.name);
  1367. if assigned(hsym) then
  1368. DuplicateSym(hsym);
  1369. end;
  1370. hp:=hp^.next;
  1371. end;
  1372. end;
  1373. { check for duplicate id in local and parsymtable symtable }
  1374. if (symtabletype=localsymtable) then
  1375. { to be on the sure side: }
  1376. begin
  1377. if assigned(next) and
  1378. (next^.symtabletype=parasymtable) then
  1379. begin
  1380. hsym:=next^.search(sym^.name);
  1381. if assigned(hsym) then
  1382. DuplicateSym(hsym);
  1383. end
  1384. else if (current_module^.flags and uf_local_browser)=0 then
  1385. internalerror(43789);
  1386. end;
  1387. { check for duplicate id in local symtable of methods }
  1388. if (symtabletype=localsymtable) and
  1389. assigned(next) and
  1390. assigned(next^.next) and
  1391. { funcretsym is allowed !! }
  1392. (sym^.typ <> funcretsym) and
  1393. (next^.next^.symtabletype=objectsymtable) then
  1394. begin
  1395. hsym:=search_class_member(pobjectdef(next^.next^.defowner),sym^.name);
  1396. { but private ids can be reused }
  1397. if assigned(hsym) and
  1398. (not(sp_private in hsym^.symoptions) or
  1399. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  1400. DuplicateSym(hsym);
  1401. end;
  1402. { check for duplicate id in para symtable of methods }
  1403. if (symtabletype=parasymtable) and
  1404. assigned(procinfo^._class) and
  1405. { but not in nested procedures !}
  1406. (not(assigned(procinfo^.parent)) or
  1407. (assigned(procinfo^.parent) and
  1408. not(assigned(procinfo^.parent^._class)))
  1409. ) and
  1410. { funcretsym is allowed !! }
  1411. (sym^.typ <> funcretsym) then
  1412. begin
  1413. hsym:=search_class_member(procinfo^._class,sym^.name);
  1414. { but private ids can be reused }
  1415. if assigned(hsym) and
  1416. (not(sp_private in hsym^.symoptions) or
  1417. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  1418. DuplicateSym(hsym);
  1419. end;
  1420. { check for duplicate field id in inherited classes }
  1421. if (sym^.typ=varsym) and
  1422. (symtabletype=objectsymtable) and
  1423. assigned(defowner) then
  1424. begin
  1425. hsym:=search_class_member(pobjectdef(defowner),sym^.name);
  1426. { but private ids can be reused }
  1427. if assigned(hsym) and
  1428. (not(sp_private in hsym^.symoptions) or
  1429. (hsym^.owner^.defowner^.owner^.symtabletype<>unitsymtable)) then
  1430. DuplicateSym(hsym);
  1431. end;
  1432. { register definition of typesym }
  1433. if (sym^.typ = typesym) and
  1434. assigned(ptypesym(sym)^.definition) then
  1435. begin
  1436. if not(assigned(ptypesym(sym)^.definition^.owner)) and
  1437. (ptypesym(sym)^.definition^.deftype<>errordef) then
  1438. registerdef(ptypesym(sym)^.definition);
  1439. {$ifdef GDB}
  1440. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  1441. (symtabletype in [globalsymtable,staticsymtable]) then
  1442. begin
  1443. ptypesym(sym)^.isusedinstab := true;
  1444. sym^.concatstabto(debuglist);
  1445. end;
  1446. {$endif GDB}
  1447. end;
  1448. { insert in index and search hash }
  1449. symindex^.insert(sym);
  1450. symsearch^.insert(sym);
  1451. insert:=sym;
  1452. end;
  1453. function tsymtable.search(const s : stringid) : psym;
  1454. begin
  1455. {search:=psym(symsearch^.search(s));
  1456. this bypasses the ref generation (PM) }
  1457. search:=speedsearch(s,getspeedvalue(s));
  1458. end;
  1459. function tsymtable.speedsearch(const s : stringid;speedvalue : longint) : psym;
  1460. var
  1461. hp : psym;
  1462. newref : pref;
  1463. begin
  1464. hp:=psym(symsearch^.speedsearch(s,speedvalue));
  1465. if assigned(hp) then
  1466. begin
  1467. { reject non static members in static procedures,
  1468. be carefull aktprocsym^.definition is not allways
  1469. loaded already (PFV) }
  1470. if (symtabletype=objectsymtable) and
  1471. not(sp_static in hp^.symoptions) and
  1472. allow_only_static
  1473. {assigned(aktprocsym) and
  1474. assigned(aktprocsym^.definition) and
  1475. ((aktprocsym^.definition^.options and postaticmethod)<>0)} then
  1476. Message(sym_e_only_static_in_static);
  1477. if (symtabletype=unitsymtable) and
  1478. assigned(punitsymtable(@self)^.unitsym) then
  1479. inc(punitsymtable(@self)^.unitsym^.refs);
  1480. { unitsym are only loaded for browsing PM }
  1481. { this was buggy anyway because we could use }
  1482. { unitsyms from other units in _USES !! }
  1483. if (symtabletype=unitsymtable) and (hp^.typ=unitsym) and
  1484. assigned(current_module) and (current_module^.globalsymtable<>@self) then
  1485. hp:=nil;
  1486. if assigned(hp) and
  1487. (cs_browser in aktmoduleswitches) and make_ref then
  1488. begin
  1489. new(newref,init(hp^.lastref,@tokenpos));
  1490. { for symbols that are in tables without
  1491. browser info or syssyms (PM) }
  1492. if hp^.refcount=0 then
  1493. begin
  1494. hp^.defref:=newref;
  1495. hp^.lastref:=newref;
  1496. end
  1497. else
  1498. if resolving_forward and assigned(hp^.defref) then
  1499. { put it as second reference }
  1500. begin
  1501. newref^.nextref:=hp^.defref^.nextref;
  1502. hp^.defref^.nextref:=newref;
  1503. hp^.lastref^.nextref:=nil;
  1504. end
  1505. else
  1506. hp^.lastref:=newref;
  1507. inc(hp^.refcount);
  1508. end;
  1509. if assigned(hp) and make_ref then
  1510. begin
  1511. inc(hp^.refs);
  1512. end;
  1513. end;
  1514. speedsearch:=hp;
  1515. end;
  1516. function tsymtable.rename(const olds,news : stringid):psym;
  1517. begin
  1518. rename:=psym(symsearch^.rename(olds,news));
  1519. end;
  1520. {***********************************************
  1521. Browser
  1522. ***********************************************}
  1523. procedure tsymtable.load_browser;
  1524. var
  1525. b : byte;
  1526. sym : psym;
  1527. prdef : pdef;
  1528. oldrecsyms : psymtable;
  1529. begin
  1530. if symtabletype in [recordsymtable,objectsymtable] then
  1531. begin
  1532. oldrecsyms:=aktrecordsymtable;
  1533. aktrecordsymtable:=@self;
  1534. end;
  1535. if symtabletype in [parasymtable,localsymtable] then
  1536. begin
  1537. oldrecsyms:=aktlocalsymtable;
  1538. aktlocalsymtable:=@self;
  1539. end;
  1540. if symtabletype=staticppusymtable then
  1541. aktstaticsymtable:=@self;
  1542. b:=current_ppu^.readentry;
  1543. if b <> ibbeginsymtablebrowser then
  1544. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1545. repeat
  1546. b:=current_ppu^.readentry;
  1547. case b of
  1548. ibsymref : begin
  1549. sym:=readsymref;
  1550. resolvesym(sym);
  1551. if assigned(sym) then
  1552. sym^.load_references;
  1553. end;
  1554. ibdefref : begin
  1555. prdef:=readdefref;
  1556. resolvedef(prdef);
  1557. if assigned(prdef) then
  1558. begin
  1559. if prdef^.deftype<>procdef then
  1560. Message(unit_f_ppu_read_error);
  1561. pprocdef(prdef)^.load_references;
  1562. end;
  1563. end;
  1564. ibendsymtablebrowser : break;
  1565. else
  1566. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1567. end;
  1568. until false;
  1569. if symtabletype in [recordsymtable,objectsymtable] then
  1570. aktrecordsymtable:=oldrecsyms;
  1571. if symtabletype in [parasymtable,localsymtable] then
  1572. aktlocalsymtable:=oldrecsyms;
  1573. end;
  1574. procedure tsymtable.write_browser;
  1575. var
  1576. oldrecsyms : psymtable;
  1577. begin
  1578. { symbol numbering for references
  1579. should have been done in write PM
  1580. number_symbols;
  1581. number_defs; }
  1582. if symtabletype in [recordsymtable,objectsymtable] then
  1583. begin
  1584. oldrecsyms:=aktrecordsymtable;
  1585. aktrecordsymtable:=@self;
  1586. end;
  1587. if symtabletype in [parasymtable,localsymtable] then
  1588. begin
  1589. oldrecsyms:=aktlocalsymtable;
  1590. aktlocalsymtable:=@self;
  1591. end;
  1592. current_ppu^.writeentry(ibbeginsymtablebrowser);
  1593. foreach({$ifndef TP}@{$endif}write_refs);
  1594. current_ppu^.writeentry(ibendsymtablebrowser);
  1595. if symtabletype in [recordsymtable,objectsymtable] then
  1596. aktrecordsymtable:=oldrecsyms;
  1597. if symtabletype in [parasymtable,localsymtable] then
  1598. aktlocalsymtable:=oldrecsyms;
  1599. end;
  1600. {$ifdef BrowserLog}
  1601. procedure tsymtable.writebrowserlog;
  1602. begin
  1603. if cs_browser in aktmoduleswitches then
  1604. begin
  1605. if assigned(name) then
  1606. Browserlog.AddLog('---Symtable '+name^)
  1607. else
  1608. begin
  1609. if (symtabletype=recordsymtable) and
  1610. assigned(defowner^.sym) then
  1611. Browserlog.AddLog('---Symtable '+defowner^.sym^.name)
  1612. else
  1613. Browserlog.AddLog('---Symtable with no name');
  1614. end;
  1615. Browserlog.Ident;
  1616. foreach({$ifndef TP}@{$endif}add_to_browserlog);
  1617. browserlog.Unident;
  1618. end;
  1619. end;
  1620. {$endif BrowserLog}
  1621. {***********************************************
  1622. Process all entries
  1623. ***********************************************}
  1624. { checks, if all procsyms and methods are defined }
  1625. procedure tsymtable.check_forwards;
  1626. begin
  1627. foreach({$ifndef TP}@{$endif}check_forward);
  1628. end;
  1629. procedure tsymtable.checklabels;
  1630. begin
  1631. foreach({$ifndef TP}@{$endif}labeldefined);
  1632. end;
  1633. procedure tsymtable.set_alignment(_alignment : byte);
  1634. var
  1635. sym : pvarsym;
  1636. l : longint;
  1637. begin
  1638. { this can not be done if there is an
  1639. hasharray ! }
  1640. alignment:=_alignment;
  1641. if (symtabletype<>parasymtable) then
  1642. internalerror(1111);
  1643. sym:=pvarsym(symindex^.first);
  1644. datasize:=0;
  1645. { there can be only varsyms }
  1646. while assigned(sym) do
  1647. begin
  1648. l:=sym^.getpushsize;
  1649. sym^.address:=datasize;
  1650. datasize:=align(datasize+l,alignment);
  1651. sym:=pvarsym(sym^.next);
  1652. end;
  1653. end;
  1654. function tsymtable.find_at_offset(l : longint) : pvarsym;
  1655. var
  1656. sym : pvarsym;
  1657. begin
  1658. find_at_offset:=nil;
  1659. { this can not be done if there is an
  1660. hasharray ! }
  1661. if (symtabletype<>parasymtable) then
  1662. internalerror(1111);
  1663. sym:=pvarsym(symindex^.first);
  1664. while assigned(sym) do
  1665. begin
  1666. if sym^.address+address_fixup=l then
  1667. begin
  1668. find_at_offset:=sym;
  1669. exit;
  1670. end;
  1671. sym:=pvarsym(sym^.next);
  1672. end;
  1673. end;
  1674. procedure tsymtable.allunitsused;
  1675. begin
  1676. foreach({$ifndef TP}@{$endif}unitsymbolused);
  1677. end;
  1678. procedure tsymtable.allsymbolsused;
  1679. begin
  1680. foreach({$ifndef TP}@{$endif}varsymbolused);
  1681. end;
  1682. procedure tsymtable.allprivatesused;
  1683. begin
  1684. foreach({$ifndef TP}@{$endif}objectprivatesymbolused);
  1685. end;
  1686. {$ifdef CHAINPROCSYMS}
  1687. procedure tsymtable.chainprocsyms;
  1688. begin
  1689. foreach({$ifndef TP}@{$endif}chainprocsym);
  1690. end;
  1691. {$endif CHAINPROCSYMS}
  1692. {$ifdef GDB}
  1693. procedure tsymtable.concatstabto(asmlist : paasmoutput);
  1694. begin
  1695. asmoutput:=asmlist;
  1696. foreach({$ifndef TP}@{$endif}concatstab);
  1697. end;
  1698. {$endif}
  1699. {****************************************************************************
  1700. TUNITSYMTABLE
  1701. ****************************************************************************}
  1702. constructor tunitsymtable.init(t : tsymtabletype; const n : string);
  1703. begin
  1704. inherited init(t);
  1705. name:=stringdup(upper(n));
  1706. unitid:=0;
  1707. unitsym:=nil;
  1708. symsearch^.usehash;
  1709. { reset GDB things }
  1710. {$ifdef GDB}
  1711. if (t = globalsymtable) then
  1712. begin
  1713. prev_dbx_counter := dbx_counter;
  1714. dbx_counter := nil;
  1715. end;
  1716. is_stab_written:=false;
  1717. dbx_count := -1;
  1718. if cs_gdb_dbx in aktglobalswitches then
  1719. begin
  1720. dbx_count := 0;
  1721. unittypecount:=1;
  1722. if (symtabletype=globalsymtable) then
  1723. pglobaltypecount := @unittypecount;
  1724. unitid:=current_module^.unitcount;
  1725. debuglist^.concat(new(pai_asm_comment,init(strpnew('Global '+name^+' has index '+tostr(unitid)))));
  1726. debuglist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0'))));
  1727. inc(current_module^.unitcount);
  1728. dbx_count_ok:=false;
  1729. dbx_counter:=@dbx_count;
  1730. do_count_dbx:=true;
  1731. end;
  1732. {$endif GDB}
  1733. end;
  1734. constructor tunitsymtable.loadasunit;
  1735. var
  1736. storeGlobalTypeCount : pword;
  1737. b : byte;
  1738. begin
  1739. unitsym:=nil;
  1740. unitid:=0;
  1741. {$ifdef GDB}
  1742. if cs_gdb_dbx in aktglobalswitches then
  1743. begin
  1744. UnitTypeCount:=1;
  1745. storeGlobalTypeCount:=PGlobalTypeCount;
  1746. PglobalTypeCount:=@UnitTypeCount;
  1747. end;
  1748. {$endif GDB}
  1749. { load symtables }
  1750. inherited load;
  1751. { set the name after because it is set to nil in tsymtable.load !! }
  1752. name:=stringdup(current_module^.modulename^);
  1753. { dbx count }
  1754. {$ifdef GDB}
  1755. if (current_module^.flags and uf_has_dbx)<>0 then
  1756. begin
  1757. b := current_ppu^.readentry;
  1758. if b <> ibdbxcount then
  1759. Message(unit_f_ppu_dbx_count_problem)
  1760. else
  1761. dbx_count := readlong;
  1762. dbx_count_ok := true;
  1763. end
  1764. else
  1765. begin
  1766. dbx_count := -1;
  1767. dbx_count_ok:=false;
  1768. end;
  1769. if cs_gdb_dbx in aktglobalswitches then
  1770. PGlobalTypeCount:=storeGlobalTypeCount;
  1771. is_stab_written:=false;
  1772. {$endif GDB}
  1773. b:=current_ppu^.readentry;
  1774. if b<>ibendimplementation then
  1775. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1776. end;
  1777. destructor tunitsymtable.done;
  1778. var
  1779. pus : punitsym;
  1780. begin
  1781. pus:=unitsym;
  1782. while assigned(pus) do
  1783. begin
  1784. unitsym:=pus^.prevsym;
  1785. pus^.prevsym:=nil;
  1786. pus^.unitsymtable:=nil;
  1787. pus:=unitsym;
  1788. end;
  1789. inherited done;
  1790. end;
  1791. procedure tunitsymtable.load_symtable_refs;
  1792. var
  1793. b : byte;
  1794. unitindex : word;
  1795. begin
  1796. if ((current_module^.flags and uf_local_browser)<>0) then
  1797. begin
  1798. current_module^.localsymtable:=new(punitsymtable,loadas(staticppusymtable));
  1799. psymtable(current_module^.localsymtable)^.name:=
  1800. stringdup('implementation of '+psymtable(current_module^.globalsymtable)^.name^);
  1801. end;
  1802. { load browser }
  1803. if (current_module^.flags and uf_has_browser)<>0 then
  1804. begin
  1805. {if not (cs_browser in aktmoduleswitches) then
  1806. current_ppu^.skipuntilentry(ibendbrowser)
  1807. else }
  1808. begin
  1809. load_browser;
  1810. unitindex:=1;
  1811. while assigned(current_module^.map^[unitindex]) do
  1812. begin
  1813. {each unit wrote one browser entry }
  1814. load_browser;
  1815. inc(unitindex);
  1816. end;
  1817. b:=current_ppu^.readentry;
  1818. if b<>ibendbrowser then
  1819. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1820. end;
  1821. end;
  1822. if ((current_module^.flags and uf_local_browser)<>0) then
  1823. psymtable(current_module^.localsymtable)^.load_browser;
  1824. end;
  1825. procedure tunitsymtable.writeasunit;
  1826. var
  1827. pu : pused_unit;
  1828. begin
  1829. { first the unitname }
  1830. current_ppu^.putstring(name^);
  1831. current_ppu^.writeentry(ibmodulename);
  1832. writesourcefiles;
  1833. writeusedmacros;
  1834. writeusedunit;
  1835. { write the objectfiles and libraries that come for this unit,
  1836. preserve the containers becuase they are still needed to load
  1837. the link.res. All doesn't depend on the crc! It doesn't matter
  1838. if a unit is in a .o or .a file }
  1839. current_ppu^.do_crc:=false;
  1840. writelinkcontainer(current_module^.linkunitofiles,iblinkunitofiles,true);
  1841. writelinkcontainer(current_module^.linkunitstaticlibs,iblinkunitstaticlibs,true);
  1842. writelinkcontainer(current_module^.linkunitsharedlibs,iblinkunitsharedlibs,true);
  1843. writelinkcontainer(current_module^.linkotherofiles,iblinkotherofiles,false);
  1844. writelinkcontainer(current_module^.linkotherstaticlibs,iblinkotherstaticlibs,true);
  1845. writelinkcontainer(current_module^.linkothersharedlibs,iblinkothersharedlibs,true);
  1846. current_ppu^.do_crc:=true;
  1847. current_ppu^.writeentry(ibendinterface);
  1848. { write the symtable entries }
  1849. inherited write;
  1850. { all after doesn't affect crc }
  1851. current_ppu^.do_crc:=false;
  1852. { write dbx count }
  1853. {$ifdef GDB}
  1854. if cs_gdb_dbx in aktglobalswitches then
  1855. begin
  1856. {$IfDef EXTDEBUG}
  1857. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1858. {$ENDIF EXTDEBUG}
  1859. current_ppu^.putlongint(dbx_count);
  1860. current_ppu^.writeentry(ibdbxcount);
  1861. end;
  1862. {$endif GDB}
  1863. current_ppu^.writeentry(ibendimplementation);
  1864. { write static symtable
  1865. needed for local debugging of unit functions }
  1866. if ((current_module^.flags and uf_local_browser)<>0) and
  1867. assigned(current_module^.localsymtable) then
  1868. psymtable(current_module^.localsymtable)^.write;
  1869. { write all browser section }
  1870. if (current_module^.flags and uf_has_browser)<>0 then
  1871. begin
  1872. write_browser;
  1873. pu:=pused_unit(current_module^.used_units.first);
  1874. while assigned(pu) do
  1875. begin
  1876. psymtable(pu^.u^.globalsymtable)^.write_browser;
  1877. pu:=pused_unit(pu^.next);
  1878. end;
  1879. current_ppu^.writeentry(ibendbrowser);
  1880. end;
  1881. if ((current_module^.flags and uf_local_browser)<>0) and
  1882. assigned(current_module^.localsymtable) then
  1883. psymtable(current_module^.localsymtable)^.write_browser;
  1884. { the last entry ibend is written automaticly }
  1885. end;
  1886. function tunitsymtable.getnewtypecount : word;
  1887. begin
  1888. {$ifdef GDB}
  1889. if not (cs_gdb_dbx in aktglobalswitches) then
  1890. getnewtypecount:=tsymtable.getnewtypecount
  1891. else
  1892. {$endif GDB}
  1893. if symtabletype = staticsymtable then
  1894. getnewtypecount:=tsymtable.getnewtypecount
  1895. else
  1896. begin
  1897. getnewtypecount:=unittypecount;
  1898. inc(unittypecount);
  1899. end;
  1900. end;
  1901. {$ifdef GDB}
  1902. procedure tunitsymtable.concattypestabto(asmlist : paasmoutput);
  1903. var prev_dbx_count : plongint;
  1904. begin
  1905. if is_stab_written then exit;
  1906. if not assigned(name) then name := stringdup('Main_program');
  1907. if (symtabletype = unitsymtable) and
  1908. (current_module^.globalsymtable<>@Self) then
  1909. begin
  1910. unitid:=current_module^.unitcount;
  1911. inc(current_module^.unitcount);
  1912. end;
  1913. asmlist^.concat(new(pai_asm_comment,init(strpnew('Begin unit '+name^
  1914. +' has index '+tostr(unitid)))));
  1915. if cs_gdb_dbx in aktglobalswitches then
  1916. begin
  1917. if dbx_count_ok then
  1918. begin
  1919. asmlist^.concat(new(pai_asm_comment,init(strpnew('"repeated" unit '+name^
  1920. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count)))));
  1921. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1922. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count)))));
  1923. exit;
  1924. end
  1925. else if (current_module^.globalsymtable<>@Self) then
  1926. begin
  1927. prev_dbx_count := dbx_counter;
  1928. dbx_counter := nil;
  1929. do_count_dbx:=false;
  1930. if symtabletype = unitsymtable then
  1931. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1932. +tostr(N_BINCL)+',0,0,0'))));
  1933. dbx_counter := @dbx_count;
  1934. dbx_count:=0;
  1935. do_count_dbx:=assigned(dbx_counter);
  1936. end;
  1937. end;
  1938. asmoutput:=asmlist;
  1939. foreach({$ifndef TP}@{$endif}concattypestab);
  1940. if cs_gdb_dbx in aktglobalswitches then
  1941. begin
  1942. if (current_module^.globalsymtable<>@Self) then
  1943. begin
  1944. dbx_counter := prev_dbx_count;
  1945. do_count_dbx:=false;
  1946. asmlist^.concat(new(pai_asm_comment,init(strpnew('End unit '+name^
  1947. +' has index '+tostr(unitid)))));
  1948. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1949. +tostr(N_EINCL)+',0,0,0'))));
  1950. do_count_dbx:=assigned(dbx_counter);
  1951. dbx_count_ok := true;
  1952. end;
  1953. end;
  1954. is_stab_written:=true;
  1955. end;
  1956. {$endif}
  1957. {****************************************************************************
  1958. Definitions
  1959. ****************************************************************************}
  1960. {$I symdef.inc}
  1961. {****************************************************************************
  1962. Symbols
  1963. ****************************************************************************}
  1964. {$I symsym.inc}
  1965. {****************************************************************************
  1966. GDB Helpers
  1967. ****************************************************************************}
  1968. {$ifdef GDB}
  1969. function typeglobalnumber(const s : string) : string;
  1970. var st : string;
  1971. symt : psymtable;
  1972. old_make_ref : boolean;
  1973. begin
  1974. old_make_ref:=make_ref;
  1975. make_ref:=false;
  1976. typeglobalnumber := '0';
  1977. srsym := nil;
  1978. if pos('.',s) > 0 then
  1979. begin
  1980. st := copy(s,1,pos('.',s)-1);
  1981. getsym(st,false);
  1982. st := copy(s,pos('.',s)+1,255);
  1983. if assigned(srsym) then
  1984. begin
  1985. if srsym^.typ = unitsym then
  1986. begin
  1987. symt := punitsym(srsym)^.unitsymtable;
  1988. srsym := symt^.search(st);
  1989. end else srsym := nil;
  1990. end;
  1991. end else st := s;
  1992. if srsym = nil then getsym(st,true);
  1993. if srsym^.typ<>typesym then
  1994. begin
  1995. Message(type_e_type_id_expected);
  1996. exit;
  1997. end;
  1998. typeglobalnumber := ptypesym(srsym)^.definition^.numberstring;
  1999. make_ref:=old_make_ref;
  2000. end;
  2001. {$endif GDB}
  2002. {****************************************************************************
  2003. Definition Helpers
  2004. ****************************************************************************}
  2005. procedure reset_global_defs;
  2006. var
  2007. def : pdef;
  2008. {$ifdef debug}
  2009. prevdef : pdef;
  2010. {$endif debug}
  2011. begin
  2012. {$ifdef debug}
  2013. prevdef:=nil;
  2014. {$endif debug}
  2015. {$ifdef GDB}
  2016. pglobaltypecount:=@globaltypecount;
  2017. {$endif GDB}
  2018. def:=firstglobaldef;
  2019. while assigned(def) do
  2020. begin
  2021. {$ifdef GDB}
  2022. if assigned(def^.sym) then
  2023. def^.sym^.isusedinstab:=false;
  2024. def^.is_def_stab_written:=false;
  2025. {$endif GDB}
  2026. {if not current_module^.in_implementation then}
  2027. begin
  2028. { reset rangenr's }
  2029. case def^.deftype of
  2030. orddef : porddef(def)^.rangenr:=0;
  2031. enumdef : penumdef(def)^.rangenr:=0;
  2032. arraydef : parraydef(def)^.rangenr:=0;
  2033. end;
  2034. if def^.deftype<>objectdef then
  2035. def^.has_rtti:=false;
  2036. def^.has_inittable:=false;
  2037. end;
  2038. {$ifdef debug}
  2039. prevdef:=def;
  2040. {$endif debug}
  2041. def:=def^.nextglobal;
  2042. end;
  2043. end;
  2044. {****************************************************************************
  2045. Object Helpers
  2046. ****************************************************************************}
  2047. function search_class_member(pd : pobjectdef;const n : string) : psym;
  2048. { searches n in symtable of pd and all anchestors }
  2049. var
  2050. sym : psym;
  2051. begin
  2052. sym:=nil;
  2053. while assigned(pd) do
  2054. begin
  2055. sym:=pd^.symtable^.search(n);
  2056. if assigned(sym) then
  2057. break;
  2058. pd:=pd^.childof;
  2059. end;
  2060. { this is needed for static methods in do_member_read pexpr unit PM
  2061. caused bug0214 }
  2062. if assigned(sym) then
  2063. begin
  2064. srsymtable:=pd^.symtable;
  2065. end;
  2066. search_class_member:=sym;
  2067. end;
  2068. var
  2069. _defaultprop : ppropertysym;
  2070. procedure testfordefaultproperty(p : pnamedindexobject);
  2071. begin
  2072. if (psym(p)^.typ=propertysym) and
  2073. (ppo_defaultproperty in ppropertysym(p)^.propoptions) then
  2074. _defaultprop:=ppropertysym(p);
  2075. end;
  2076. function search_default_property(pd : pobjectdef) : ppropertysym;
  2077. { returns the default property of a class, searches also anchestors }
  2078. begin
  2079. _defaultprop:=nil;
  2080. while assigned(pd) do
  2081. begin
  2082. pd^.symtable^.foreach({$ifndef TP}@{$endif}testfordefaultproperty);
  2083. if assigned(_defaultprop) then
  2084. break;
  2085. pd:=pd^.childof;
  2086. end;
  2087. search_default_property:=_defaultprop;
  2088. end;
  2089. {****************************************************************************
  2090. Macro's
  2091. ****************************************************************************}
  2092. procedure def_macro(const s : string);
  2093. var
  2094. mac : pmacrosym;
  2095. begin
  2096. mac:=pmacrosym(macros^.search(s));
  2097. if mac=nil then
  2098. begin
  2099. mac:=new(pmacrosym,init(s));
  2100. Message1(parser_m_macro_defined,mac^.name);
  2101. macros^.insert(mac);
  2102. end;
  2103. mac^.defined:=true;
  2104. mac^.defined_at_startup:=true;
  2105. end;
  2106. procedure set_macro(const s : string;value : string);
  2107. var
  2108. mac : pmacrosym;
  2109. begin
  2110. mac:=pmacrosym(macros^.search(s));
  2111. if mac=nil then
  2112. begin
  2113. mac:=new(pmacrosym,init(s));
  2114. macros^.insert(mac);
  2115. end
  2116. else
  2117. begin
  2118. if assigned(mac^.buftext) then
  2119. freemem(mac^.buftext,mac^.buflen);
  2120. end;
  2121. Message2(parser_m_macro_set_to,mac^.name,value);
  2122. mac^.buflen:=length(value);
  2123. getmem(mac^.buftext,mac^.buflen);
  2124. move(value[1],mac^.buftext^,mac^.buflen);
  2125. mac^.defined:=true;
  2126. mac^.defined_at_startup:=true;
  2127. end;
  2128. {$ifdef UNITALIASES}
  2129. {****************************************************************************
  2130. TUNIT_ALIAS
  2131. ****************************************************************************}
  2132. constructor tunit_alias.init(const n:string);
  2133. var
  2134. i : longint;
  2135. begin
  2136. i:=pos('=',n);
  2137. if i=0 then
  2138. fail;
  2139. inherited initname(Copy(n,1,i-1));
  2140. newname:=stringdup(Copy(n,i+1,255));
  2141. end;
  2142. destructor tunit_alias.done;
  2143. begin
  2144. stringdispose(newname);
  2145. inherited done;
  2146. end;
  2147. procedure addunitalias(const n:string);
  2148. begin
  2149. unitaliases^.insert(new(punit_alias,init(Upper(n))));
  2150. end;
  2151. function getunitalias(const n:string):string;
  2152. var
  2153. p : punit_alias;
  2154. begin
  2155. p:=punit_alias(unitaliases^.search(Upper(n)));
  2156. if assigned(p) then
  2157. getunitalias:=punit_alias(p)^.newname^
  2158. else
  2159. getunitalias:=n;
  2160. end;
  2161. {$endif UNITALIASES}
  2162. {****************************************************************************
  2163. Symtable Stack
  2164. ****************************************************************************}
  2165. procedure dellexlevel;
  2166. var
  2167. p : psymtable;
  2168. begin
  2169. p:=symtablestack;
  2170. symtablestack:=p^.next;
  2171. { symbol tables of unit interfaces are never disposed }
  2172. { this is handle by the unit unitm }
  2173. if not(p^.symtabletype in [unitsymtable,globalsymtable,stt_exceptsymtable]) or dispose_global then
  2174. dispose(p,done);
  2175. end;
  2176. {$ifdef DEBUG}
  2177. procedure test_symtablestack;
  2178. var
  2179. p : psymtable;
  2180. i : longint;
  2181. begin
  2182. p:=symtablestack;
  2183. i:=0;
  2184. while assigned(p) do
  2185. begin
  2186. inc(i);
  2187. p:=p^.next;
  2188. if i>500 then
  2189. Message(sym_f_internal_error_in_symtablestack);
  2190. end;
  2191. end;
  2192. procedure list_symtablestack;
  2193. var
  2194. p : psymtable;
  2195. i : longint;
  2196. begin
  2197. p:=symtablestack;
  2198. i:=0;
  2199. while assigned(p) do
  2200. begin
  2201. inc(i);
  2202. writeln(i,' ',p^.name^);
  2203. p:=p^.next;
  2204. if i>500 then
  2205. Message(sym_f_internal_error_in_symtablestack);
  2206. end;
  2207. end;
  2208. {$endif DEBUG}
  2209. {****************************************************************************
  2210. Init/Done Symtable
  2211. ****************************************************************************}
  2212. {$ifndef Delphi}
  2213. {$ifdef tp}
  2214. procedure do_streamerror;
  2215. begin
  2216. if symbolstream.status=-2 then
  2217. WriteLn('Error: Not enough EMS memory')
  2218. else
  2219. WriteLn('Error: EMS Error ',symbolstream.status);
  2220. halt(1);
  2221. end;
  2222. {$endif TP}
  2223. {$endif Delphi}
  2224. procedure InitSymtable;
  2225. begin
  2226. {$ifndef Delphi}
  2227. {$ifdef TP}
  2228. { Allocate stream }
  2229. if use_big then
  2230. begin
  2231. streamerror:=@do_streamerror;
  2232. { symbolstream.init('TMPFILE',stcreate,16000); }
  2233. {$ifndef dpmi}
  2234. symbolstream.init(10000,4000000); {using ems streams}
  2235. {$else}
  2236. symbolstream.init(1000000,16000); {using memory streams}
  2237. {$endif}
  2238. if symbolstream.errorinfo=stiniterror then
  2239. do_streamerror;
  2240. { write something, because pos 0 means nil pointer }
  2241. symbolstream.writestr(@inputfile);
  2242. end;
  2243. {$endif tp}
  2244. {$endif Delphi}
  2245. { Reset symbolstack }
  2246. registerdef:=false;
  2247. read_member:=false;
  2248. symtablestack:=nil;
  2249. systemunit:=nil;
  2250. {$ifdef GDB}
  2251. firstglobaldef:=nil;
  2252. lastglobaldef:=nil;
  2253. {$endif GDB}
  2254. globaltypecount:=1;
  2255. pglobaltypecount:=@globaltypecount;
  2256. { create error syms and def }
  2257. generrorsym:=new(perrorsym,init);
  2258. generrordef:=new(perrordef,init);
  2259. {$ifdef UNITALIASES}
  2260. { unit aliases }
  2261. unitaliases:=new(pdictionary,init);
  2262. {$endif}
  2263. for token:=first_overloaded to last_overloaded do
  2264. overloaded_operators[token]:=nil;
  2265. end;
  2266. procedure DoneSymtable;
  2267. begin
  2268. dispose(generrorsym,done);
  2269. dispose(generrordef,done);
  2270. {$ifdef UNITALIASES}
  2271. dispose(unitaliases,done);
  2272. {$endif}
  2273. {$ifndef Delphi}
  2274. {$ifdef TP}
  2275. { close the stream }
  2276. if use_big then
  2277. symbolstream.done;
  2278. {$endif}
  2279. {$endif Delphi}
  2280. end;
  2281. end.
  2282. {
  2283. $Log$
  2284. Revision 1.67 1999-11-24 11:41:05 pierre
  2285. * defaultsymtablestack is now restored after parser.compile
  2286. Revision 1.66 1999/11/22 00:23:09 pierre
  2287. * also complain about unused functions in program
  2288. Revision 1.65 1999/11/19 14:49:15 pierre
  2289. * avoid certain wrong notes/hints
  2290. Revision 1.64 1999/11/18 15:34:48 pierre
  2291. * Notes/Hints for local syms changed to
  2292. Set_varstate function
  2293. Revision 1.63 1999/11/17 17:05:06 pierre
  2294. * Notes/hints changes
  2295. Revision 1.62 1999/11/15 22:00:48 peter
  2296. * labels used but not defined give error instead of warning, the warning
  2297. is now only with declared but not defined and not used.
  2298. Revision 1.61 1999/11/15 17:52:59 pierre
  2299. + one field added for ttoken record for operator
  2300. linking the id to the corresponding operator token that
  2301. can now now all be overloaded
  2302. * overloaded operators are resetted to nil in InitSymtable
  2303. (bug when trying to compile a uint that overloads operators twice)
  2304. Revision 1.60 1999/11/09 23:35:50 pierre
  2305. + better reference pos for forward defs
  2306. Revision 1.59 1999/11/06 16:21:57 jonas
  2307. + search optimial register to use in alignment code (compile with
  2308. -dalignreg, -dalignregdebug to see chosen register in
  2309. assembler code). Still needs support in ag386bin.
  2310. Revision 1.58 1999/11/06 14:34:28 peter
  2311. * truncated log to 20 revs
  2312. Revision 1.57 1999/11/05 17:18:03 pierre
  2313. * local browsing works at first level
  2314. ie for function defined in interface or implementation
  2315. not yet for functions inside other functions
  2316. Revision 1.56 1999/11/04 23:13:25 peter
  2317. * moved unit alias support into ifdef
  2318. Revision 1.55 1999/11/04 10:54:02 peter
  2319. + -Ua<oldname>=<newname> unit alias support
  2320. Revision 1.54 1999/10/26 12:30:46 peter
  2321. * const parameter is now checked
  2322. * better and generic check if a node can be used for assigning
  2323. * export fixes
  2324. * procvar equal works now (it never had worked at least from 0.99.8)
  2325. * defcoll changed to linkedlist with pparaitem so it can easily be
  2326. walked both directions
  2327. Revision 1.53 1999/10/06 17:39:15 peter
  2328. * fixed stabs writting for forward types
  2329. Revision 1.52 1999/10/03 19:44:42 peter
  2330. * removed objpasunit reference, tvarrec is now searched in systemunit
  2331. where it already was located
  2332. Revision 1.51 1999/10/01 08:02:49 peter
  2333. * forward type declaration rewritten
  2334. Revision 1.50 1999/09/28 20:48:25 florian
  2335. * fixed bug 610
  2336. + added $D- for TP in symtable.pas else it can't be compiled anymore
  2337. (too much symbols :()
  2338. Revision 1.49 1999/09/27 23:44:59 peter
  2339. * procinfo is now a pointer
  2340. * support for result setting in sub procedure
  2341. Revision 1.48 1999/09/12 21:35:38 florian
  2342. * fixed a crash under Linux. Why doesn't have the damned Windows DPMI nil pointer
  2343. protection???
  2344. Revision 1.47 1999/09/12 08:48:09 florian
  2345. * bugs 593 and 607 fixed
  2346. * some other potential bugs with array constructors fixed
  2347. * for classes compiled in $M+ and it's childs, the default access method
  2348. is now published
  2349. * fixed copyright message (it is now 1993-99)
  2350. Revision 1.46 1999/09/10 18:48:10 florian
  2351. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  2352. * most things for stored properties fixed
  2353. Revision 1.45 1999/09/08 08:05:44 peter
  2354. * fixed bug 248
  2355. Revision 1.44 1999/08/31 15:46:21 pierre
  2356. * do_crc must be false for all browser stuff
  2357. + tmacrosym defined_at_startup set in def_macro and set_macro
  2358. Revision 1.43 1999/08/27 10:39:24 pierre
  2359. * uf_local_browser made problem when computing interface CRC
  2360. Revision 1.42 1999/08/13 21:33:13 peter
  2361. * support for array constructors extended and more error checking
  2362. Revision 1.41 1999/08/13 14:24:22 pierre
  2363. + stabs for classes and classref working,
  2364. a class still needs an ^ to get that content of it,
  2365. but the class fields inside a class don't result into an
  2366. infinite loop anymore!
  2367. Revision 1.40 1999/08/10 16:25:42 pierre
  2368. * unitid changed to word
  2369. Revision 1.39 1999/08/10 12:33:36 pierre
  2370. * pprocsym defined earlier for use in tprocdef
  2371. Revision 1.38 1999/08/05 16:53:18 peter
  2372. * V_Fatal=1, all other V_ are also increased
  2373. * Check for local procedure when assigning procvar
  2374. * fixed comment parsing because directives
  2375. * oldtp mode directives better supported
  2376. * added some messages to errore.msg
  2377. }