symtable.pas 84 KB

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