symtable.pas 80 KB

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