symtable.pas 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564
  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. begin
  1393. hp:=psym(symsearch^.speedsearch(s,speedvalue));
  1394. if assigned(hp) then
  1395. begin
  1396. { reject non static members in static procedures,
  1397. be carefull aktprocsym^.definition is not allways
  1398. loaded already (PFV) }
  1399. if (symtabletype=objectsymtable) and
  1400. not(sp_static in hp^.symoptions) and
  1401. allow_only_static
  1402. {assigned(aktprocsym) and
  1403. assigned(aktprocsym^.definition) and
  1404. ((aktprocsym^.definition^.options and postaticmethod)<>0)} then
  1405. Message(sym_e_only_static_in_static);
  1406. if (symtabletype=unitsymtable) and
  1407. assigned(punitsymtable(@self)^.unitsym) then
  1408. inc(punitsymtable(@self)^.unitsym^.refs);
  1409. { unitsym are only loaded for browsing PM }
  1410. { this was buggy anyway because we could use }
  1411. { unitsyms from other units in _USES !! }
  1412. if (symtabletype=unitsymtable) and (hp^.typ=unitsym) and
  1413. assigned(current_module) and (current_module^.globalsymtable<>@self) then
  1414. hp:=nil;
  1415. if assigned(hp) and
  1416. (cs_browser in aktmoduleswitches) and make_ref then
  1417. begin
  1418. hp^.lastref:=new(pref,init(hp^.lastref,@tokenpos));
  1419. { for symbols that are in tables without
  1420. browser info or syssyms (PM) }
  1421. if hp^.refcount=0 then
  1422. hp^.defref:=hp^.lastref;
  1423. inc(hp^.refcount);
  1424. end;
  1425. end;
  1426. speedsearch:=hp;
  1427. end;
  1428. function tsymtable.rename(const olds,news : stringid):psym;
  1429. begin
  1430. rename:=psym(symsearch^.rename(olds,news));
  1431. end;
  1432. {***********************************************
  1433. Browser
  1434. ***********************************************}
  1435. procedure tsymtable.load_browser;
  1436. var
  1437. b : byte;
  1438. sym : psym;
  1439. prdef : pdef;
  1440. oldrecsyms : psymtable;
  1441. begin
  1442. if symtabletype in [recordsymtable,objectsymtable] then
  1443. begin
  1444. oldrecsyms:=aktrecordsymtable;
  1445. aktrecordsymtable:=@self;
  1446. end;
  1447. if symtabletype in [parasymtable,localsymtable] then
  1448. begin
  1449. oldrecsyms:=aktlocalsymtable;
  1450. aktlocalsymtable:=@self;
  1451. end;
  1452. if symtabletype=staticppusymtable then
  1453. aktstaticsymtable:=@self;
  1454. b:=current_ppu^.readentry;
  1455. if b <> ibbeginsymtablebrowser then
  1456. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1457. repeat
  1458. b:=current_ppu^.readentry;
  1459. case b of
  1460. ibsymref : begin
  1461. sym:=readsymref;
  1462. resolvesym(sym);
  1463. if assigned(sym) then
  1464. sym^.load_references;
  1465. end;
  1466. ibdefref : begin
  1467. prdef:=readdefref;
  1468. resolvedef(prdef);
  1469. if assigned(prdef) then
  1470. begin
  1471. if prdef^.deftype<>procdef then
  1472. Message(unit_f_ppu_read_error);
  1473. pprocdef(prdef)^.load_references;
  1474. end;
  1475. end;
  1476. ibendsymtablebrowser : break;
  1477. else
  1478. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1479. end;
  1480. until false;
  1481. if symtabletype in [recordsymtable,objectsymtable] then
  1482. aktrecordsymtable:=oldrecsyms;
  1483. if symtabletype in [parasymtable,localsymtable] then
  1484. aktlocalsymtable:=oldrecsyms;
  1485. end;
  1486. procedure tsymtable.write_browser;
  1487. var
  1488. oldrecsyms : psymtable;
  1489. begin
  1490. { symbol numbering for references
  1491. should have been done in write PM
  1492. number_symbols;
  1493. number_defs; }
  1494. if symtabletype in [recordsymtable,objectsymtable] then
  1495. begin
  1496. oldrecsyms:=aktrecordsymtable;
  1497. aktrecordsymtable:=@self;
  1498. end;
  1499. if symtabletype in [parasymtable,localsymtable] then
  1500. begin
  1501. oldrecsyms:=aktlocalsymtable;
  1502. aktlocalsymtable:=@self;
  1503. end;
  1504. current_ppu^.writeentry(ibbeginsymtablebrowser);
  1505. foreach({$ifndef TP}@{$endif}write_refs);
  1506. current_ppu^.writeentry(ibendsymtablebrowser);
  1507. if symtabletype in [recordsymtable,objectsymtable] then
  1508. aktrecordsymtable:=oldrecsyms;
  1509. if symtabletype in [parasymtable,localsymtable] then
  1510. aktlocalsymtable:=oldrecsyms;
  1511. end;
  1512. {$ifdef BrowserLog}
  1513. procedure tsymtable.writebrowserlog;
  1514. begin
  1515. if cs_browser in aktmoduleswitches then
  1516. begin
  1517. if assigned(name) then
  1518. Browserlog.AddLog('---Symtable '+name^)
  1519. else
  1520. begin
  1521. if (symtabletype=recordsymtable) and
  1522. assigned(defowner^.sym) then
  1523. Browserlog.AddLog('---Symtable '+defowner^.sym^.name)
  1524. else
  1525. Browserlog.AddLog('---Symtable with no name');
  1526. end;
  1527. Browserlog.Ident;
  1528. foreach({$ifndef TP}@{$endif}add_to_browserlog);
  1529. browserlog.Unident;
  1530. end;
  1531. end;
  1532. {$endif BrowserLog}
  1533. {***********************************************
  1534. Process all entries
  1535. ***********************************************}
  1536. { checks, if all procsyms and methods are defined }
  1537. procedure tsymtable.check_forwards;
  1538. begin
  1539. foreach({$ifndef TP}@{$endif}check_forward);
  1540. end;
  1541. procedure tsymtable.checklabels;
  1542. begin
  1543. foreach({$ifndef TP}@{$endif}labeldefined);
  1544. end;
  1545. procedure tsymtable.set_alignment(_alignment : byte);
  1546. var
  1547. sym : pvarsym;
  1548. l : longint;
  1549. begin
  1550. { this can not be done if there is an
  1551. hasharray ! }
  1552. alignment:=_alignment;
  1553. if (symtabletype<>parasymtable) then
  1554. internalerror(1111);
  1555. sym:=pvarsym(symindex^.first);
  1556. datasize:=0;
  1557. { there can be only varsyms }
  1558. while assigned(sym) do
  1559. begin
  1560. l:=sym^.getpushsize;
  1561. sym^.address:=datasize;
  1562. datasize:=align(datasize+l,alignment);
  1563. sym:=pvarsym(sym^.next);
  1564. end;
  1565. end;
  1566. function tsymtable.find_at_offset(l : longint) : pvarsym;
  1567. var
  1568. sym : pvarsym;
  1569. begin
  1570. find_at_offset:=nil;
  1571. { this can not be done if there is an
  1572. hasharray ! }
  1573. if (symtabletype<>parasymtable) then
  1574. internalerror(1111);
  1575. sym:=pvarsym(symindex^.first);
  1576. while assigned(sym) do
  1577. begin
  1578. if sym^.address+address_fixup=l then
  1579. begin
  1580. find_at_offset:=sym;
  1581. exit;
  1582. end;
  1583. sym:=pvarsym(sym^.next);
  1584. end;
  1585. end;
  1586. procedure tsymtable.allunitsused;
  1587. begin
  1588. foreach({$ifndef TP}@{$endif}unitsymbolused);
  1589. end;
  1590. procedure tsymtable.allsymbolsused;
  1591. begin
  1592. foreach({$ifndef TP}@{$endif}varsymbolused);
  1593. end;
  1594. {$ifdef CHAINPROCSYMS}
  1595. procedure tsymtable.chainprocsyms;
  1596. begin
  1597. foreach({$ifndef TP}@{$endif}chainprocsym);
  1598. end;
  1599. {$endif CHAINPROCSYMS}
  1600. {$ifdef GDB}
  1601. procedure tsymtable.concatstabto(asmlist : paasmoutput);
  1602. begin
  1603. asmoutput:=asmlist;
  1604. foreach({$ifndef TP}@{$endif}concatstab);
  1605. end;
  1606. {$endif}
  1607. {****************************************************************************
  1608. TUNITSYMTABLE
  1609. ****************************************************************************}
  1610. constructor tunitsymtable.init(t : tsymtabletype; const n : string);
  1611. begin
  1612. inherited init(t);
  1613. name:=stringdup(upper(n));
  1614. unitid:=0;
  1615. unitsym:=nil;
  1616. symsearch^.usehash;
  1617. { reset GDB things }
  1618. {$ifdef GDB}
  1619. if (t = globalsymtable) then
  1620. begin
  1621. prev_dbx_counter := dbx_counter;
  1622. dbx_counter := nil;
  1623. end;
  1624. is_stab_written:=false;
  1625. dbx_count := -1;
  1626. if cs_gdb_dbx in aktglobalswitches then
  1627. begin
  1628. dbx_count := 0;
  1629. unittypecount:=1;
  1630. if (symtabletype=globalsymtable) then
  1631. pglobaltypecount := @unittypecount;
  1632. unitid:=current_module^.unitcount;
  1633. debuglist^.concat(new(pai_asm_comment,init(strpnew('Global '+name^+' has index '+tostr(unitid)))));
  1634. debuglist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0'))));
  1635. inc(current_module^.unitcount);
  1636. dbx_count_ok:=false;
  1637. dbx_counter:=@dbx_count;
  1638. do_count_dbx:=true;
  1639. end;
  1640. {$endif GDB}
  1641. end;
  1642. constructor tunitsymtable.loadasunit;
  1643. var
  1644. storeGlobalTypeCount : pword;
  1645. b : byte;
  1646. begin
  1647. unitsym:=nil;
  1648. unitid:=0;
  1649. {$ifdef GDB}
  1650. if cs_gdb_dbx in aktglobalswitches then
  1651. begin
  1652. UnitTypeCount:=1;
  1653. storeGlobalTypeCount:=PGlobalTypeCount;
  1654. PglobalTypeCount:=@UnitTypeCount;
  1655. end;
  1656. {$endif GDB}
  1657. { load symtables }
  1658. inherited load;
  1659. { set the name after because it is set to nil in tsymtable.load !! }
  1660. name:=stringdup(current_module^.modulename^);
  1661. { dbx count }
  1662. {$ifdef GDB}
  1663. if (current_module^.flags and uf_has_dbx)<>0 then
  1664. begin
  1665. b := current_ppu^.readentry;
  1666. if b <> ibdbxcount then
  1667. Message(unit_f_ppu_dbx_count_problem)
  1668. else
  1669. dbx_count := readlong;
  1670. dbx_count_ok := true;
  1671. end
  1672. else
  1673. begin
  1674. dbx_count := -1;
  1675. dbx_count_ok:=false;
  1676. end;
  1677. if cs_gdb_dbx in aktglobalswitches then
  1678. PGlobalTypeCount:=storeGlobalTypeCount;
  1679. is_stab_written:=false;
  1680. {$endif GDB}
  1681. b:=current_ppu^.readentry;
  1682. if b<>ibendimplementation then
  1683. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1684. end;
  1685. destructor tunitsymtable.done;
  1686. var
  1687. pus : punitsym;
  1688. begin
  1689. pus:=unitsym;
  1690. while assigned(pus) do
  1691. begin
  1692. unitsym:=pus^.prevsym;
  1693. pus^.prevsym:=nil;
  1694. pus^.unitsymtable:=nil;
  1695. pus:=unitsym;
  1696. end;
  1697. inherited done;
  1698. end;
  1699. procedure tunitsymtable.load_symtable_refs;
  1700. var
  1701. b : byte;
  1702. unitindex : word;
  1703. begin
  1704. if ((current_module^.flags and uf_local_browser)<>0) then
  1705. begin
  1706. current_module^.localsymtable:=new(punitsymtable,loadas(staticppusymtable));
  1707. psymtable(current_module^.localsymtable)^.name:=
  1708. stringdup('implementation of '+psymtable(current_module^.globalsymtable)^.name^);
  1709. end;
  1710. { load browser }
  1711. if (current_module^.flags and uf_has_browser)<>0 then
  1712. begin
  1713. {if not (cs_browser in aktmoduleswitches) then
  1714. current_ppu^.skipuntilentry(ibendbrowser)
  1715. else }
  1716. begin
  1717. load_browser;
  1718. unitindex:=1;
  1719. while assigned(current_module^.map^[unitindex]) do
  1720. begin
  1721. {each unit wrote one browser entry }
  1722. load_browser;
  1723. inc(unitindex);
  1724. end;
  1725. b:=current_ppu^.readentry;
  1726. if b<>ibendbrowser then
  1727. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1728. end;
  1729. end;
  1730. if ((current_module^.flags and uf_local_browser)<>0) then
  1731. psymtable(current_module^.localsymtable)^.load_browser;
  1732. end;
  1733. procedure tunitsymtable.writeasunit;
  1734. var
  1735. pu : pused_unit;
  1736. begin
  1737. { first the unitname }
  1738. current_ppu^.putstring(name^);
  1739. current_ppu^.writeentry(ibmodulename);
  1740. writesourcefiles;
  1741. writeusedmacros;
  1742. writeusedunit;
  1743. { write the objectfiles and libraries that come for this unit,
  1744. preserve the containers becuase they are still needed to load
  1745. the link.res. All doesn't depend on the crc! It doesn't matter
  1746. if a unit is in a .o or .a file }
  1747. current_ppu^.do_crc:=false;
  1748. writelinkcontainer(current_module^.linkunitofiles,iblinkunitofiles,true);
  1749. writelinkcontainer(current_module^.linkunitstaticlibs,iblinkunitstaticlibs,true);
  1750. writelinkcontainer(current_module^.linkunitsharedlibs,iblinkunitsharedlibs,true);
  1751. writelinkcontainer(current_module^.linkotherofiles,iblinkotherofiles,false);
  1752. writelinkcontainer(current_module^.linkotherstaticlibs,iblinkotherstaticlibs,true);
  1753. writelinkcontainer(current_module^.linkothersharedlibs,iblinkothersharedlibs,true);
  1754. current_ppu^.do_crc:=true;
  1755. current_ppu^.writeentry(ibendinterface);
  1756. { write the symtable entries }
  1757. inherited write;
  1758. { all after doesn't affect crc }
  1759. current_ppu^.do_crc:=false;
  1760. { write dbx count }
  1761. {$ifdef GDB}
  1762. if cs_gdb_dbx in aktglobalswitches then
  1763. begin
  1764. {$IfDef EXTDEBUG}
  1765. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1766. {$ENDIF EXTDEBUG}
  1767. current_ppu^.putlongint(dbx_count);
  1768. current_ppu^.writeentry(ibdbxcount);
  1769. end;
  1770. {$endif GDB}
  1771. current_ppu^.writeentry(ibendimplementation);
  1772. { write static symtable
  1773. needed for local debugging of unit functions }
  1774. if ((current_module^.flags and uf_local_browser)<>0) and
  1775. assigned(current_module^.localsymtable) then
  1776. psymtable(current_module^.localsymtable)^.write;
  1777. { write all browser section }
  1778. if (current_module^.flags and uf_has_browser)<>0 then
  1779. begin
  1780. write_browser;
  1781. pu:=pused_unit(current_module^.used_units.first);
  1782. while assigned(pu) do
  1783. begin
  1784. psymtable(pu^.u^.globalsymtable)^.write_browser;
  1785. pu:=pused_unit(pu^.next);
  1786. end;
  1787. current_ppu^.writeentry(ibendbrowser);
  1788. end;
  1789. if ((current_module^.flags and uf_local_browser)<>0) and
  1790. assigned(current_module^.localsymtable) then
  1791. psymtable(current_module^.localsymtable)^.write_browser;
  1792. { the last entry ibend is written automaticly }
  1793. end;
  1794. function tunitsymtable.getnewtypecount : word;
  1795. begin
  1796. {$ifdef GDB}
  1797. if not (cs_gdb_dbx in aktglobalswitches) then
  1798. getnewtypecount:=tsymtable.getnewtypecount
  1799. else
  1800. {$endif GDB}
  1801. if symtabletype = staticsymtable then
  1802. getnewtypecount:=tsymtable.getnewtypecount
  1803. else
  1804. begin
  1805. getnewtypecount:=unittypecount;
  1806. inc(unittypecount);
  1807. end;
  1808. end;
  1809. {$ifdef GDB}
  1810. procedure tunitsymtable.concattypestabto(asmlist : paasmoutput);
  1811. var prev_dbx_count : plongint;
  1812. begin
  1813. if is_stab_written then exit;
  1814. if not assigned(name) then name := stringdup('Main_program');
  1815. if (symtabletype = unitsymtable) and
  1816. (current_module^.globalsymtable<>@Self) then
  1817. begin
  1818. unitid:=current_module^.unitcount;
  1819. inc(current_module^.unitcount);
  1820. end;
  1821. asmlist^.concat(new(pai_asm_comment,init(strpnew('Begin unit '+name^
  1822. +' has index '+tostr(unitid)))));
  1823. if cs_gdb_dbx in aktglobalswitches then
  1824. begin
  1825. if dbx_count_ok then
  1826. begin
  1827. asmlist^.concat(new(pai_asm_comment,init(strpnew('"repeated" unit '+name^
  1828. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count)))));
  1829. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1830. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count)))));
  1831. exit;
  1832. end
  1833. else if (current_module^.globalsymtable<>@Self) then
  1834. begin
  1835. prev_dbx_count := dbx_counter;
  1836. dbx_counter := nil;
  1837. do_count_dbx:=false;
  1838. if symtabletype = unitsymtable then
  1839. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1840. +tostr(N_BINCL)+',0,0,0'))));
  1841. dbx_counter := @dbx_count;
  1842. dbx_count:=0;
  1843. do_count_dbx:=assigned(dbx_counter);
  1844. end;
  1845. end;
  1846. asmoutput:=asmlist;
  1847. foreach({$ifndef TP}@{$endif}concattypestab);
  1848. if cs_gdb_dbx in aktglobalswitches then
  1849. begin
  1850. if (current_module^.globalsymtable<>@Self) then
  1851. begin
  1852. dbx_counter := prev_dbx_count;
  1853. do_count_dbx:=false;
  1854. asmlist^.concat(new(pai_asm_comment,init(strpnew('End unit '+name^
  1855. +' has index '+tostr(unitid)))));
  1856. asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
  1857. +tostr(N_EINCL)+',0,0,0'))));
  1858. do_count_dbx:=assigned(dbx_counter);
  1859. dbx_count_ok := true;
  1860. end;
  1861. end;
  1862. is_stab_written:=true;
  1863. end;
  1864. {$endif}
  1865. {****************************************************************************
  1866. Definitions
  1867. ****************************************************************************}
  1868. {$I symdef.inc}
  1869. {****************************************************************************
  1870. Symbols
  1871. ****************************************************************************}
  1872. {$I symsym.inc}
  1873. {****************************************************************************
  1874. GDB Helpers
  1875. ****************************************************************************}
  1876. {$ifdef GDB}
  1877. function typeglobalnumber(const s : string) : string;
  1878. var st : string;
  1879. symt : psymtable;
  1880. old_make_ref : boolean;
  1881. begin
  1882. old_make_ref:=make_ref;
  1883. make_ref:=false;
  1884. typeglobalnumber := '0';
  1885. srsym := nil;
  1886. if pos('.',s) > 0 then
  1887. begin
  1888. st := copy(s,1,pos('.',s)-1);
  1889. getsym(st,false);
  1890. st := copy(s,pos('.',s)+1,255);
  1891. if assigned(srsym) then
  1892. begin
  1893. if srsym^.typ = unitsym then
  1894. begin
  1895. symt := punitsym(srsym)^.unitsymtable;
  1896. srsym := symt^.search(st);
  1897. end else srsym := nil;
  1898. end;
  1899. end else st := s;
  1900. if srsym = nil then getsym(st,true);
  1901. if srsym^.typ<>typesym then
  1902. begin
  1903. Message(type_e_type_id_expected);
  1904. exit;
  1905. end;
  1906. typeglobalnumber := ptypesym(srsym)^.definition^.numberstring;
  1907. make_ref:=old_make_ref;
  1908. end;
  1909. {$endif GDB}
  1910. {****************************************************************************
  1911. Definition Helpers
  1912. ****************************************************************************}
  1913. procedure reset_global_defs;
  1914. var
  1915. def : pdef;
  1916. {$ifdef debug}
  1917. prevdef : pdef;
  1918. {$endif debug}
  1919. begin
  1920. {$ifdef debug}
  1921. prevdef:=nil;
  1922. {$endif debug}
  1923. {$ifdef GDB}
  1924. pglobaltypecount:=@globaltypecount;
  1925. {$endif GDB}
  1926. def:=firstglobaldef;
  1927. while assigned(def) do
  1928. begin
  1929. {$ifdef GDB}
  1930. if assigned(def^.sym) then
  1931. def^.sym^.isusedinstab:=false;
  1932. def^.is_def_stab_written:=false;
  1933. {$endif GDB}
  1934. {if not current_module^.in_implementation then}
  1935. begin
  1936. { reset rangenr's }
  1937. case def^.deftype of
  1938. orddef : porddef(def)^.rangenr:=0;
  1939. enumdef : penumdef(def)^.rangenr:=0;
  1940. arraydef : parraydef(def)^.rangenr:=0;
  1941. end;
  1942. if def^.deftype<>objectdef then
  1943. def^.has_rtti:=false;
  1944. def^.has_inittable:=false;
  1945. end;
  1946. {$ifdef debug}
  1947. prevdef:=def;
  1948. {$endif debug}
  1949. def:=def^.nextglobal;
  1950. end;
  1951. end;
  1952. {****************************************************************************
  1953. Object Helpers
  1954. ****************************************************************************}
  1955. function search_class_member(pd : pobjectdef;const n : string) : psym;
  1956. { searches n in symtable of pd and all anchestors }
  1957. var
  1958. sym : psym;
  1959. begin
  1960. sym:=nil;
  1961. while assigned(pd) do
  1962. begin
  1963. sym:=pd^.symtable^.search(n);
  1964. if assigned(sym) then
  1965. break;
  1966. pd:=pd^.childof;
  1967. end;
  1968. { this is needed for static methods in do_member_read pexpr unit PM
  1969. caused bug0214 }
  1970. if assigned(sym) then
  1971. begin
  1972. srsymtable:=pd^.symtable;
  1973. end;
  1974. search_class_member:=sym;
  1975. end;
  1976. var
  1977. _defaultprop : ppropertysym;
  1978. procedure testfordefaultproperty(p : pnamedindexobject);
  1979. begin
  1980. if (psym(p)^.typ=propertysym) and
  1981. (ppo_defaultproperty in ppropertysym(p)^.propoptions) then
  1982. _defaultprop:=ppropertysym(p);
  1983. end;
  1984. function search_default_property(pd : pobjectdef) : ppropertysym;
  1985. { returns the default property of a class, searches also anchestors }
  1986. begin
  1987. _defaultprop:=nil;
  1988. while assigned(pd) do
  1989. begin
  1990. pd^.symtable^.foreach({$ifndef TP}@{$endif}testfordefaultproperty);
  1991. if assigned(_defaultprop) then
  1992. break;
  1993. pd:=pd^.childof;
  1994. end;
  1995. search_default_property:=_defaultprop;
  1996. end;
  1997. {****************************************************************************
  1998. Macro's
  1999. ****************************************************************************}
  2000. procedure def_macro(const s : string);
  2001. var
  2002. mac : pmacrosym;
  2003. begin
  2004. mac:=pmacrosym(macros^.search(s));
  2005. if mac=nil then
  2006. begin
  2007. mac:=new(pmacrosym,init(s));
  2008. Message1(parser_m_macro_defined,mac^.name);
  2009. macros^.insert(mac);
  2010. end;
  2011. mac^.defined:=true;
  2012. mac^.defined_at_startup:=true;
  2013. end;
  2014. procedure set_macro(const s : string;value : 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. macros^.insert(mac);
  2023. end
  2024. else
  2025. begin
  2026. if assigned(mac^.buftext) then
  2027. freemem(mac^.buftext,mac^.buflen);
  2028. end;
  2029. Message2(parser_m_macro_set_to,mac^.name,value);
  2030. mac^.buflen:=length(value);
  2031. getmem(mac^.buftext,mac^.buflen);
  2032. move(value[1],mac^.buftext^,mac^.buflen);
  2033. mac^.defined:=true;
  2034. mac^.defined_at_startup:=true;
  2035. end;
  2036. {$ifdef UNITALIASES}
  2037. {****************************************************************************
  2038. TUNIT_ALIAS
  2039. ****************************************************************************}
  2040. constructor tunit_alias.init(const n:string);
  2041. var
  2042. i : longint;
  2043. begin
  2044. i:=pos('=',n);
  2045. if i=0 then
  2046. fail;
  2047. inherited initname(Copy(n,1,i-1));
  2048. newname:=stringdup(Copy(n,i+1,255));
  2049. end;
  2050. destructor tunit_alias.done;
  2051. begin
  2052. stringdispose(newname);
  2053. inherited done;
  2054. end;
  2055. procedure addunitalias(const n:string);
  2056. begin
  2057. unitaliases^.insert(new(punit_alias,init(Upper(n))));
  2058. end;
  2059. function getunitalias(const n:string):string;
  2060. var
  2061. p : punit_alias;
  2062. begin
  2063. p:=punit_alias(unitaliases^.search(Upper(n)));
  2064. if assigned(p) then
  2065. getunitalias:=punit_alias(p)^.newname^
  2066. else
  2067. getunitalias:=n;
  2068. end;
  2069. {$endif UNITALIASES}
  2070. {****************************************************************************
  2071. Symtable Stack
  2072. ****************************************************************************}
  2073. procedure dellexlevel;
  2074. var
  2075. p : psymtable;
  2076. begin
  2077. p:=symtablestack;
  2078. symtablestack:=p^.next;
  2079. { symbol tables of unit interfaces are never disposed }
  2080. { this is handle by the unit unitm }
  2081. if not(p^.symtabletype in [unitsymtable,globalsymtable,stt_exceptsymtable]) or dispose_global then
  2082. dispose(p,done);
  2083. end;
  2084. {$ifdef DEBUG}
  2085. procedure test_symtablestack;
  2086. var
  2087. p : psymtable;
  2088. i : longint;
  2089. begin
  2090. p:=symtablestack;
  2091. i:=0;
  2092. while assigned(p) do
  2093. begin
  2094. inc(i);
  2095. p:=p^.next;
  2096. if i>500 then
  2097. Message(sym_f_internal_error_in_symtablestack);
  2098. end;
  2099. end;
  2100. procedure list_symtablestack;
  2101. var
  2102. p : psymtable;
  2103. i : longint;
  2104. begin
  2105. p:=symtablestack;
  2106. i:=0;
  2107. while assigned(p) do
  2108. begin
  2109. inc(i);
  2110. writeln(i,' ',p^.name^);
  2111. p:=p^.next;
  2112. if i>500 then
  2113. Message(sym_f_internal_error_in_symtablestack);
  2114. end;
  2115. end;
  2116. {$endif DEBUG}
  2117. {****************************************************************************
  2118. Init/Done Symtable
  2119. ****************************************************************************}
  2120. {$ifndef Delphi}
  2121. {$ifdef tp}
  2122. procedure do_streamerror;
  2123. begin
  2124. if symbolstream.status=-2 then
  2125. WriteLn('Error: Not enough EMS memory')
  2126. else
  2127. WriteLn('Error: EMS Error ',symbolstream.status);
  2128. halt(1);
  2129. end;
  2130. {$endif TP}
  2131. {$endif Delphi}
  2132. procedure InitSymtable;
  2133. begin
  2134. {$ifndef Delphi}
  2135. {$ifdef TP}
  2136. { Allocate stream }
  2137. if use_big then
  2138. begin
  2139. streamerror:=@do_streamerror;
  2140. { symbolstream.init('TMPFILE',stcreate,16000); }
  2141. {$ifndef dpmi}
  2142. symbolstream.init(10000,4000000); {using ems streams}
  2143. {$else}
  2144. symbolstream.init(1000000,16000); {using memory streams}
  2145. {$endif}
  2146. if symbolstream.errorinfo=stiniterror then
  2147. do_streamerror;
  2148. { write something, because pos 0 means nil pointer }
  2149. symbolstream.writestr(@inputfile);
  2150. end;
  2151. {$endif tp}
  2152. {$endif Delphi}
  2153. { Reset symbolstack }
  2154. registerdef:=false;
  2155. read_member:=false;
  2156. symtablestack:=nil;
  2157. systemunit:=nil;
  2158. {$ifdef GDB}
  2159. firstglobaldef:=nil;
  2160. lastglobaldef:=nil;
  2161. {$endif GDB}
  2162. globaltypecount:=1;
  2163. pglobaltypecount:=@globaltypecount;
  2164. { create error syms and def }
  2165. generrorsym:=new(perrorsym,init);
  2166. generrordef:=new(perrordef,init);
  2167. {$ifdef UNITALIASES}
  2168. { unit aliases }
  2169. unitaliases:=new(pdictionary,init);
  2170. {$endif}
  2171. end;
  2172. procedure DoneSymtable;
  2173. begin
  2174. dispose(generrorsym,done);
  2175. dispose(generrordef,done);
  2176. {$ifdef UNITALIASES}
  2177. dispose(unitaliases,done);
  2178. {$endif}
  2179. {$ifndef Delphi}
  2180. {$ifdef TP}
  2181. { close the stream }
  2182. if use_big then
  2183. symbolstream.done;
  2184. {$endif}
  2185. {$endif Delphi}
  2186. end;
  2187. end.
  2188. {
  2189. $Log$
  2190. Revision 1.59 1999-11-06 16:21:57 jonas
  2191. + search optimial register to use in alignment code (compile with
  2192. -dalignreg, -dalignregdebug to see chosen register in
  2193. assembler code). Still needs support in ag386bin.
  2194. Revision 1.58 1999/11/06 14:34:28 peter
  2195. * truncated log to 20 revs
  2196. Revision 1.57 1999/11/05 17:18:03 pierre
  2197. * local browsing works at first level
  2198. ie for function defined in interface or implementation
  2199. not yet for functions inside other functions
  2200. Revision 1.56 1999/11/04 23:13:25 peter
  2201. * moved unit alias support into ifdef
  2202. Revision 1.55 1999/11/04 10:54:02 peter
  2203. + -Ua<oldname>=<newname> unit alias support
  2204. Revision 1.54 1999/10/26 12:30:46 peter
  2205. * const parameter is now checked
  2206. * better and generic check if a node can be used for assigning
  2207. * export fixes
  2208. * procvar equal works now (it never had worked at least from 0.99.8)
  2209. * defcoll changed to linkedlist with pparaitem so it can easily be
  2210. walked both directions
  2211. Revision 1.53 1999/10/06 17:39:15 peter
  2212. * fixed stabs writting for forward types
  2213. Revision 1.52 1999/10/03 19:44:42 peter
  2214. * removed objpasunit reference, tvarrec is now searched in systemunit
  2215. where it already was located
  2216. Revision 1.51 1999/10/01 08:02:49 peter
  2217. * forward type declaration rewritten
  2218. Revision 1.50 1999/09/28 20:48:25 florian
  2219. * fixed bug 610
  2220. + added $D- for TP in symtable.pas else it can't be compiled anymore
  2221. (too much symbols :()
  2222. Revision 1.49 1999/09/27 23:44:59 peter
  2223. * procinfo is now a pointer
  2224. * support for result setting in sub procedure
  2225. Revision 1.48 1999/09/12 21:35:38 florian
  2226. * fixed a crash under Linux. Why doesn't have the damned Windows DPMI nil pointer
  2227. protection???
  2228. Revision 1.47 1999/09/12 08:48:09 florian
  2229. * bugs 593 and 607 fixed
  2230. * some other potential bugs with array constructors fixed
  2231. * for classes compiled in $M+ and it's childs, the default access method
  2232. is now published
  2233. * fixed copyright message (it is now 1993-99)
  2234. Revision 1.46 1999/09/10 18:48:10 florian
  2235. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  2236. * most things for stored properties fixed
  2237. Revision 1.45 1999/09/08 08:05:44 peter
  2238. * fixed bug 248
  2239. Revision 1.44 1999/08/31 15:46:21 pierre
  2240. * do_crc must be false for all browser stuff
  2241. + tmacrosym defined_at_startup set in def_macro and set_macro
  2242. Revision 1.43 1999/08/27 10:39:24 pierre
  2243. * uf_local_browser made problem when computing interface CRC
  2244. Revision 1.42 1999/08/13 21:33:13 peter
  2245. * support for array constructors extended and more error checking
  2246. Revision 1.41 1999/08/13 14:24:22 pierre
  2247. + stabs for classes and classref working,
  2248. a class still needs an ^ to get that content of it,
  2249. but the class fields inside a class don't result into an
  2250. infinite loop anymore!
  2251. Revision 1.40 1999/08/10 16:25:42 pierre
  2252. * unitid changed to word
  2253. Revision 1.39 1999/08/10 12:33:36 pierre
  2254. * pprocsym defined earlier for use in tprocdef
  2255. Revision 1.38 1999/08/05 16:53:18 peter
  2256. * V_Fatal=1, all other V_ are also increased
  2257. * Check for local procedure when assigning procvar
  2258. * fixed comment parsing because directives
  2259. * oldtp mode directives better supported
  2260. * added some messages to errore.msg
  2261. }