symtable.pas 84 KB

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