symtable.pas 84 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. unit symtable;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,symsym,
  28. { assembler }
  29. aasm
  30. ;
  31. {****************************************************************************
  32. Symtable types
  33. ****************************************************************************}
  34. type
  35. tstoredsymtable = class(tsymtable)
  36. private
  37. b_needs_init_final : boolean;
  38. procedure _needs_init_final(p : tnamedindexitem);
  39. procedure check_forward(sym : TNamedIndexItem);
  40. procedure labeldefined(p : TNamedIndexItem);
  41. procedure unitsymbolused(p : TNamedIndexItem);
  42. procedure varsymbolused(p : TNamedIndexItem);
  43. procedure TestPrivate(p : TNamedIndexItem);
  44. procedure objectprivatesymbolused(p : TNamedIndexItem);
  45. {$ifdef GDB}
  46. private
  47. asmoutput : taasmoutput;
  48. procedure concatstab(p : TNamedIndexItem);
  49. procedure resetstab(p : TNamedIndexItem);
  50. procedure concattypestab(p : TNamedIndexItem);
  51. {$endif}
  52. procedure order_overloads(p : TNamedIndexItem);
  53. procedure loaddefs;
  54. procedure loadsyms;
  55. procedure writedefs;
  56. procedure writesyms;
  57. public
  58. { load/write }
  59. procedure load;virtual;
  60. procedure write;virtual;
  61. procedure load_browser;virtual;
  62. procedure write_browser;virtual;
  63. procedure deref;virtual;
  64. procedure insert(sym : tsymentry);override;
  65. function speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;override;
  66. procedure allsymbolsused;
  67. procedure allprivatesused;
  68. procedure allunitsused;
  69. procedure check_forwards;
  70. procedure checklabels;
  71. function needs_init_final : boolean;
  72. { change alignment for args only parasymtable }
  73. procedure set_alignment(_alignment : longint);
  74. {$ifdef CHAINPROCSYMS}
  75. procedure chainprocsyms;
  76. {$endif CHAINPROCSYMS}
  77. procedure chainoperators;
  78. {$ifdef GDB}
  79. procedure concatstabto(asmlist : taasmoutput);virtual;
  80. function getnewtypecount : word; override;
  81. {$endif GDB}
  82. procedure testfordefaultproperty(p : TNamedIndexItem);
  83. end;
  84. tabstractrecordsymtable = class(tstoredsymtable)
  85. public
  86. procedure load;override;
  87. procedure write;override;
  88. procedure load_browser;override;
  89. procedure write_browser;override;
  90. end;
  91. trecordsymtable = class(tabstractrecordsymtable)
  92. public
  93. constructor create;
  94. procedure insert_in(tsymt : tsymtable;offset : longint);
  95. end;
  96. tobjectsymtable = class(tabstractrecordsymtable)
  97. public
  98. constructor create(const n:string);
  99. procedure insert(sym : tsymentry);override;
  100. end;
  101. tabstractlocalsymtable = class(tstoredsymtable)
  102. public
  103. procedure load;override;
  104. procedure write;override;
  105. procedure load_browser;override;
  106. procedure write_browser;override;
  107. end;
  108. tlocalsymtable = class(tabstractlocalsymtable)
  109. public
  110. constructor create;
  111. procedure insert(sym : tsymentry);override;
  112. end;
  113. tparasymtable = class(tabstractlocalsymtable)
  114. public
  115. constructor create;
  116. procedure insert(sym : tsymentry);override;
  117. end;
  118. tabstractunitsymtable = class(tstoredsymtable)
  119. public
  120. {$ifdef GDB}
  121. dbx_count : longint;
  122. prev_dbx_counter : plongint;
  123. dbx_count_ok : boolean;
  124. is_stab_written : boolean;
  125. {$endif GDB}
  126. constructor create(const n : string);
  127. {$ifdef GDB}
  128. procedure concattypestabto(asmlist : taasmoutput);
  129. {$endif GDB}
  130. end;
  131. tglobalsymtable = class(tabstractunitsymtable)
  132. private
  133. procedure writeusedmacro(p:TNamedIndexItem);
  134. public
  135. unittypecount : word;
  136. unitsym : tunitsym;
  137. constructor create(const n : string);
  138. destructor destroy;
  139. procedure load;override;
  140. procedure write;override;
  141. procedure load_symtable_refs;
  142. {$ifdef GDB}
  143. function getnewtypecount : word; override;
  144. {$endif}
  145. procedure writeusedmacros;
  146. end;
  147. tstaticsymtable = class(tabstractunitsymtable)
  148. public
  149. constructor create(const n : string);
  150. procedure load;override;
  151. procedure write;override;
  152. procedure load_browser;override;
  153. procedure write_browser;override;
  154. procedure insert(sym : tsymentry);override;
  155. end;
  156. twithsymtable = class(tsymtable)
  157. direct_with : boolean;
  158. { in fact it is a tnode }
  159. withnode : pointer;
  160. { tnode to load of direct with var }
  161. { already usable before firstwith
  162. needed for firstpass of function parameters PM }
  163. withrefnode : pointer;
  164. constructor create(aowner:tdef;asymsearch:TDictionary);
  165. destructor destroy;override;
  166. procedure clear;override;
  167. end;
  168. tstt_exceptsymtable = class(tsymtable)
  169. public
  170. constructor create;
  171. end;
  172. var
  173. constsymtable : tsymtable; { symtable were the constants can be inserted }
  174. systemunit : tglobalsymtable; { pointer to the system unit }
  175. read_member : boolean; { reading members of an symtable }
  176. lexlevel : longint; { level of code }
  177. { 1 for main procedure }
  178. { 2 for normal function or proc }
  179. { higher for locals }
  180. {****************************************************************************
  181. Functions
  182. ****************************************************************************}
  183. {*** Misc ***}
  184. procedure globaldef(const s : string;var t:ttype);
  185. function findunitsymtable(st:tsymtable):tsymtable;
  186. procedure duplicatesym(sym:tsym);
  187. procedure identifier_not_found(const s:string);
  188. {*** Search ***}
  189. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  190. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  191. function search_class_member(pd : tobjectdef;const s : string):tsym;
  192. {*** PPU Write/Loading ***}
  193. procedure writeunitas(const s : string;unittable : tglobalsymtable;only_crc : boolean);
  194. procedure numberunits;
  195. procedure load_interface;
  196. {*** Object Helpers ***}
  197. function search_default_property(pd : tobjectdef) : tpropertysym;
  198. {*** symtable stack ***}
  199. procedure dellexlevel;
  200. procedure RestoreUnitSyms;
  201. {$ifdef DEBUG}
  202. procedure test_symtablestack;
  203. procedure list_symtablestack;
  204. {$endif DEBUG}
  205. {$ifdef UNITALIASES}
  206. type
  207. punit_alias = ^tunit_alias;
  208. tunit_alias = object(TNamedIndexItem)
  209. newname : pstring;
  210. constructor init(const n:string);
  211. destructor done;virtual;
  212. end;
  213. var
  214. unitaliases : pdictionary;
  215. procedure addunitalias(const n:string);
  216. function getunitalias(const n:string):string;
  217. {$endif UNITALIASES}
  218. {*** Init / Done ***}
  219. procedure InitSymtable;
  220. procedure DoneSymtable;
  221. const
  222. { last operator which can be overloaded, the first_overloaded should
  223. be in tokens.pas after NOTOKEN }
  224. first_overloaded = _PLUS;
  225. last_overloaded = _ASSIGNMENT;
  226. type
  227. toverloaded_operators = array[NOTOKEN..last_overloaded] of tprocsym;
  228. var
  229. overloaded_operators : toverloaded_operators;
  230. { unequal is not equal}
  231. const
  232. overloaded_names : array [NOTOKEN..last_overloaded] of string[16] =
  233. ('error',
  234. 'plus','minus','star','slash','equal',
  235. 'greater','lower','greater_or_equal',
  236. 'lower_or_equal',
  237. 'sym_diff','starstar',
  238. 'as','is','in','or',
  239. 'and','div','mod','not','shl','shr','xor',
  240. 'assign');
  241. implementation
  242. uses
  243. { global }
  244. version,verbose,globals,
  245. { target }
  246. systems,
  247. { ppu }
  248. symppu,ppu,
  249. { module }
  250. finput,fmodule,
  251. {$ifdef GDB}
  252. gdb,
  253. {$endif GDB}
  254. { scanner }
  255. scanner,
  256. { codegen }
  257. hcodegen
  258. ;
  259. var
  260. in_loading : boolean; { remove !!! }
  261. {*****************************************************************************
  262. TStoredSymtable
  263. *****************************************************************************}
  264. procedure tstoredsymtable.load;
  265. begin
  266. { load definitions }
  267. loaddefs;
  268. { load symbols }
  269. loadsyms;
  270. end;
  271. procedure tstoredsymtable.write;
  272. begin
  273. { write definitions }
  274. writedefs;
  275. { write symbols }
  276. writesyms;
  277. end;
  278. procedure tstoredsymtable.loaddefs;
  279. var
  280. hp : tdef;
  281. b : byte;
  282. begin
  283. { load start of definition section, which holds the amount of defs }
  284. if current_ppu^.readentry<>ibstartdefs then
  285. Message(unit_f_ppu_read_error);
  286. current_ppu^.getlongint;
  287. { read definitions }
  288. repeat
  289. b:=current_ppu^.readentry;
  290. case b of
  291. ibpointerdef : hp:=tpointerdef.load;
  292. ibarraydef : hp:=tarraydef.load;
  293. iborddef : hp:=torddef.load;
  294. ibfloatdef : hp:=tfloatdef.load;
  295. ibprocdef : hp:=tprocdef.load;
  296. ibshortstringdef : hp:=tstringdef.loadshort;
  297. iblongstringdef : hp:=tstringdef.loadlong;
  298. ibansistringdef : hp:=tstringdef.loadansi;
  299. ibwidestringdef : hp:=tstringdef.loadwide;
  300. ibrecorddef : hp:=trecorddef.load;
  301. ibobjectdef : hp:=tobjectdef.load;
  302. ibenumdef : hp:=tenumdef.load;
  303. ibsetdef : hp:=tsetdef.load;
  304. ibprocvardef : hp:=tprocvardef.load;
  305. ibfiledef : hp:=tfiledef.load;
  306. ibclassrefdef : hp:=tclassrefdef.load;
  307. ibformaldef : hp:=tformaldef.load;
  308. ibvariantdef : hp:=tvariantdef.load;
  309. ibenddefs : break;
  310. ibend : Message(unit_f_ppu_read_error);
  311. else
  312. Message1(unit_f_ppu_invalid_entry,tostr(b));
  313. end;
  314. hp.owner:=self;
  315. defindex.insert(hp);
  316. until false;
  317. end;
  318. procedure tstoredsymtable.loadsyms;
  319. var
  320. b : byte;
  321. sym : tsym;
  322. begin
  323. { load start of definition section, which holds the amount of defs }
  324. if current_ppu^.readentry<>ibstartsyms then
  325. Message(unit_f_ppu_read_error);
  326. { skip amount of symbols, not used currently }
  327. current_ppu^.getlongint;
  328. { load datasize,dataalignment of this symboltable }
  329. datasize:=current_ppu^.getlongint;
  330. dataalignment:=current_ppu^.getlongint;
  331. { now read the symbols }
  332. repeat
  333. b:=current_ppu^.readentry;
  334. case b of
  335. ibtypesym : sym:=ttypesym.load;
  336. ibprocsym : sym:=tprocsym.load;
  337. ibconstsym : sym:=tconstsym.load;
  338. ibvarsym : sym:=tvarsym.load;
  339. ibfuncretsym : sym:=tfuncretsym.load;
  340. ibabsolutesym : sym:=tabsolutesym.load;
  341. ibenumsym : sym:=tenumsym.load;
  342. ibtypedconstsym : sym:=ttypedconstsym.load;
  343. ibpropertysym : sym:=tpropertysym.load;
  344. ibunitsym : sym:=tunitsym.load;
  345. iblabelsym : sym:=tlabelsym.load;
  346. ibsyssym : sym:=tsyssym.load;
  347. ibendsyms : break;
  348. ibend : Message(unit_f_ppu_read_error);
  349. else
  350. Message1(unit_f_ppu_invalid_entry,tostr(b));
  351. end;
  352. sym.owner:=self;
  353. symindex.insert(sym);
  354. symsearch.insert(sym);
  355. until false;
  356. end;
  357. procedure tstoredsymtable.writedefs;
  358. var
  359. pd : tstoreddef;
  360. begin
  361. { each definition get a number, write then the amount of defs to the
  362. ibstartdef entry }
  363. current_ppu^.putlongint(defindex.count);
  364. current_ppu^.writeentry(ibstartdefs);
  365. { now write the definition }
  366. pd:=tstoreddef(defindex.first);
  367. while assigned(pd) do
  368. begin
  369. pd.write;
  370. pd:=tstoreddef(pd.indexnext);
  371. end;
  372. { write end of definitions }
  373. current_ppu^.writeentry(ibenddefs);
  374. end;
  375. procedure tstoredsymtable.writesyms;
  376. var
  377. pd : tstoredsym;
  378. begin
  379. { each definition get a number, write then the amount of syms and the
  380. datasize to the ibsymdef entry }
  381. current_ppu^.putlongint(symindex.count);
  382. current_ppu^.putlongint(datasize);
  383. current_ppu^.putlongint(dataalignment);
  384. current_ppu^.writeentry(ibstartsyms);
  385. { foreach is used to write all symbols }
  386. pd:=tstoredsym(symindex.first);
  387. while assigned(pd) do
  388. begin
  389. pd.write;
  390. pd:=tstoredsym(pd.indexnext);
  391. end;
  392. { end of symbols }
  393. current_ppu^.writeentry(ibendsyms);
  394. end;
  395. procedure tstoredsymtable.load_browser;
  396. var
  397. b : byte;
  398. sym : tstoredsym;
  399. prdef : tstoreddef;
  400. begin
  401. b:=current_ppu^.readentry;
  402. if b <> ibbeginsymtablebrowser then
  403. Message1(unit_f_ppu_invalid_entry,tostr(b));
  404. repeat
  405. b:=current_ppu^.readentry;
  406. case b of
  407. ibsymref :
  408. begin
  409. sym:=tstoredsym(readderef);
  410. resolvesym(tsym(sym));
  411. if assigned(sym) then
  412. sym.load_references;
  413. end;
  414. ibdefref :
  415. begin
  416. prdef:=tstoreddef(readderef);
  417. resolvedef(tdef(prdef));
  418. if assigned(prdef) then
  419. begin
  420. if prdef.deftype<>procdef then
  421. Message(unit_f_ppu_read_error);
  422. tprocdef(prdef).load_references;
  423. end;
  424. end;
  425. ibendsymtablebrowser :
  426. break;
  427. else
  428. Message1(unit_f_ppu_invalid_entry,tostr(b));
  429. end;
  430. until false;
  431. end;
  432. procedure tstoredsymtable.write_browser;
  433. var
  434. pd : tstoredsym;
  435. begin
  436. current_ppu^.writeentry(ibbeginsymtablebrowser);
  437. { foreach is used to write all symbols }
  438. pd:=tstoredsym(symindex.first);
  439. while assigned(pd) do
  440. begin
  441. pd.write_references;
  442. pd:=tstoredsym(pd.indexnext);
  443. end;
  444. current_ppu^.writeentry(ibendsymtablebrowser);
  445. end;
  446. procedure tstoredsymtable.deref;
  447. var
  448. hp : tdef;
  449. hs : tsym;
  450. begin
  451. { deref the definitions }
  452. hp:=tdef(defindex.first);
  453. while assigned(hp) do
  454. begin
  455. hp.deref;
  456. hp:=tdef(hp.indexnext);
  457. end;
  458. { first deref the ttypesyms }
  459. hs:=tsym(symindex.first);
  460. while assigned(hs) do
  461. begin
  462. hs.prederef;
  463. hs:=tsym(hs.indexnext);
  464. end;
  465. { deref the symbols }
  466. hs:=tsym(symindex.first);
  467. while assigned(hs) do
  468. begin
  469. hs.deref;
  470. hs:=tsym(hs.indexnext);
  471. end;
  472. end;
  473. procedure tstoredsymtable.insert(sym:tsymentry);
  474. var
  475. hsym : tsym;
  476. begin
  477. { set owner and sym indexnb }
  478. sym.owner:=self;
  479. {$ifdef CHAINPROCSYMS}
  480. { set the nextprocsym field }
  481. if sym.typ=procsym then
  482. chainprocsym(sym);
  483. {$endif CHAINPROCSYMS}
  484. { writes the symbol in data segment if required }
  485. { also sets the datasize of owner }
  486. if not in_loading then
  487. tstoredsym(sym).insert_in_data;
  488. { check the current symtable }
  489. hsym:=tsym(search(sym.name));
  490. if assigned(hsym) then
  491. begin
  492. { in TP and Delphi you can have a local with the
  493. same name as the function, the function is then hidden for
  494. the user. (Under delphi it can still be accessed using result),
  495. but don't allow hiding of RESULT }
  496. if (m_tp in aktmodeswitches) and
  497. (hsym.typ=funcretsym) and
  498. not((m_result in aktmodeswitches) and
  499. (hsym.name='RESULT')) then
  500. hsym.owner.rename(hsym.name,'hidden'+hsym.name)
  501. else
  502. begin
  503. DuplicateSym(hsym);
  504. exit;
  505. end;
  506. end;
  507. { register definition of typesym }
  508. if (sym.typ = typesym) and
  509. assigned(ttypesym(sym).restype.def) then
  510. begin
  511. if not(assigned(ttypesym(sym).restype.def.owner)) and
  512. (ttypesym(sym).restype.def.deftype<>errordef) then
  513. registerdef(ttypesym(sym).restype.def);
  514. {$ifdef GDB}
  515. if (cs_debuginfo in aktmoduleswitches) and assigned(debuglist) and
  516. (symtabletype in [globalsymtable,staticsymtable]) then
  517. begin
  518. ttypesym(sym).isusedinstab := true;
  519. {sym.concatstabto(debuglist);}
  520. end;
  521. {$endif GDB}
  522. end;
  523. { insert in index and search hash }
  524. symindex.insert(sym);
  525. symsearch.insert(sym);
  526. end;
  527. function tstoredsymtable.speedsearch(const s : stringid;speedvalue : cardinal) : tsymentry;
  528. var
  529. hp : tstoredsym;
  530. newref : tref;
  531. begin
  532. hp:=tstoredsym(inherited speedsearch(s,speedvalue));
  533. if assigned(hp) then
  534. begin
  535. { reject non static members in static procedures,
  536. be carefull aktprocsym.definition is not allways
  537. loaded already (PFV) }
  538. if (symtabletype=objectsymtable) and
  539. not(sp_static in hp.symoptions) and
  540. allow_only_static
  541. {assigned(aktprocsym) and
  542. assigned(aktprocsym.definition) and
  543. ((aktprocsym.definition.options and postaticmethod)<>0)} then
  544. Message(sym_e_only_static_in_static);
  545. if (unitid<>0) and
  546. assigned(tglobalsymtable(self).unitsym) then
  547. inc(tglobalsymtable(self).unitsym.refs);
  548. {$ifdef GDB}
  549. { if it is a type, we need the stabs of this type
  550. this might be the cause of the class debug problems
  551. as TCHILDCLASS.Create did not generate appropriate
  552. stabs debug info if TCHILDCLASS wasn't used anywhere else PM }
  553. if (hp.typ=typesym) and make_ref then
  554. begin
  555. if assigned(ttypesym(hp).restype.def) then
  556. tstoreddef(ttypesym(hp).restype.def).numberstring
  557. else
  558. ttypesym(hp).isusedinstab:=true;
  559. end;
  560. {$endif GDB}
  561. { unitsym are only loaded for browsing PM }
  562. { this was buggy anyway because we could use }
  563. { unitsyms from other units in _USES !! }
  564. {if (symtabletype=unitsymtable) and (hp.typ=unitsym) and
  565. assigned(current_module) and (current_module.globalsymtable<>.load) then
  566. hp:=nil;}
  567. if assigned(hp) and
  568. (cs_browser in aktmoduleswitches) and make_ref then
  569. begin
  570. newref:=tref.create(hp.lastref,@akttokenpos);
  571. { for symbols that are in tables without
  572. browser info or syssyms (PM) }
  573. if hp.refcount=0 then
  574. begin
  575. hp.defref:=newref;
  576. hp.lastref:=newref;
  577. end
  578. else
  579. if resolving_forward and assigned(hp.defref) then
  580. { put it as second reference }
  581. begin
  582. newref.nextref:=hp.defref.nextref;
  583. hp.defref.nextref:=newref;
  584. hp.lastref.nextref:=nil;
  585. end
  586. else
  587. hp.lastref:=newref;
  588. inc(hp.refcount);
  589. end;
  590. if assigned(hp) and make_ref then
  591. begin
  592. inc(hp.refs);
  593. end;
  594. end;
  595. speedsearch:=hp;
  596. end;
  597. {**************************************
  598. Callbacks
  599. **************************************}
  600. procedure TStoredSymtable.check_forward(sym : TNamedIndexItem);
  601. begin
  602. if tsym(sym).typ=procsym then
  603. tprocsym(sym).check_forward
  604. { check also object method table }
  605. { we needn't to test the def list }
  606. { because each object has to have a type sym }
  607. else
  608. if (tsym(sym).typ=typesym) and
  609. assigned(ttypesym(sym).restype.def) and
  610. (ttypesym(sym).restype.def.deftype=objectdef) then
  611. tobjectdef(ttypesym(sym).restype.def).check_forwards;
  612. end;
  613. procedure TStoredSymtable.labeldefined(p : TNamedIndexItem);
  614. begin
  615. if (tsym(p).typ=labelsym) and
  616. not(tlabelsym(p).defined) then
  617. begin
  618. if tlabelsym(p).used then
  619. Message1(sym_e_label_used_and_not_defined,tlabelsym(p).realname)
  620. else
  621. Message1(sym_w_label_not_defined,tlabelsym(p).realname);
  622. end;
  623. end;
  624. procedure TStoredSymtable.unitsymbolused(p : TNamedIndexItem);
  625. begin
  626. if (tsym(p).typ=unitsym) and
  627. (tunitsym(p).refs=0) and
  628. { do not claim for unit name itself !! }
  629. (tunitsym(p).unitsymtable.symtabletype=globalsymtable) then
  630. MessagePos2(tsym(p).fileinfo,sym_n_unit_not_used,
  631. p.name,current_module.modulename^);
  632. end;
  633. procedure TStoredSymtable.varsymbolused(p : TNamedIndexItem);
  634. begin
  635. if (tsym(p).typ=varsym) and
  636. ((tsym(p).owner.symtabletype in
  637. [parasymtable,localsymtable,objectsymtable,staticsymtable])) then
  638. begin
  639. { unused symbol should be reported only if no }
  640. { error is reported }
  641. { if the symbol is in a register it is used }
  642. { also don't count the value parameters which have local copies }
  643. { also don't claim for high param of open parameters (PM) }
  644. if (Errorcount<>0) or
  645. (copy(p.name,1,3)='val') or
  646. (copy(p.name,1,4)='high') then
  647. exit;
  648. if (tvarsym(p).refs=0) then
  649. begin
  650. if (tsym(p).owner.symtabletype=parasymtable) or (vo_is_local_copy in tvarsym(p).varoptions) then
  651. begin
  652. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_not_used,tsym(p).realname);
  653. end
  654. else if (tsym(p).owner.symtabletype=objectsymtable) then
  655. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_not_used,tsym(p).owner.name^,tsym(p).realname)
  656. else
  657. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_not_used,tsym(p).realname);
  658. end
  659. else if tvarsym(p).varstate=vs_assigned then
  660. begin
  661. if (tsym(p).owner.symtabletype=parasymtable) then
  662. begin
  663. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  664. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname)
  665. end
  666. else if (vo_is_local_copy in tvarsym(p).varoptions) then
  667. begin
  668. if not(tvarsym(p).varspez in [vs_var,vs_out]) then
  669. MessagePos1(tsym(p).fileinfo,sym_h_para_identifier_only_set,tsym(p).realname);
  670. end
  671. else if (tsym(p).owner.symtabletype=objectsymtable) then
  672. MessagePos2(tsym(p).fileinfo,sym_n_private_identifier_only_set,tsym(p).owner.name^,tsym(p).realname)
  673. else if (tsym(p).owner.symtabletype<>parasymtable) then
  674. if not (vo_is_exported in tvarsym(p).varoptions) then
  675. MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_only_set,tsym(p).realname);
  676. end;
  677. end
  678. else if ((tsym(p).owner.symtabletype in
  679. [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
  680. begin
  681. if (Errorcount<>0) then
  682. exit;
  683. { do not claim for inherited private fields !! }
  684. if (tstoredsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
  685. MessagePos2(tsym(p).fileinfo,sym_n_private_method_not_used,tsym(p).owner.name^,tsym(p).realname)
  686. { units references are problematic }
  687. else if (tstoredsym(p).refs=0) and not(tsym(p).typ in [funcretsym,enumsym,unitsym]) then
  688. if (tsym(p).typ<>procsym) or not (tprocsym(p).is_global) or
  689. { all program functions are declared global
  690. but unused should still be signaled PM }
  691. ((tsym(p).owner.symtabletype=staticsymtable) and
  692. not current_module.is_unit) then
  693. MessagePos2(tsym(p).fileinfo,sym_h_local_symbol_not_used,SymTypeName[tsym(p).typ],tsym(p).realname);
  694. end;
  695. end;
  696. procedure TStoredSymtable.TestPrivate(p : TNamedIndexItem);
  697. begin
  698. if sp_private in tsym(p).symoptions then
  699. varsymbolused(p);
  700. end;
  701. procedure TStoredSymtable.objectprivatesymbolused(p : TNamedIndexItem);
  702. begin
  703. {
  704. Don't test simple object aliases PM
  705. }
  706. if (tsym(p).typ=typesym) and
  707. (ttypesym(p).restype.def.deftype=objectdef) and
  708. (ttypesym(p).restype.def.typesym=tsym(p)) then
  709. tobjectdef(ttypesym(p).restype.def).symtable.foreach({$ifdef FPCPROCVAR}@{$endif}TestPrivate);
  710. end;
  711. procedure tstoredsymtable.order_overloads(p : TNamedIndexItem);
  712. begin
  713. if tsym(p).typ=procsym then
  714. tprocsym(p).order_overloaded;
  715. end;
  716. {$ifdef GDB}
  717. procedure TStoredSymtable.concatstab(p : TNamedIndexItem);
  718. begin
  719. if tsym(p).typ <> procsym then
  720. tstoredsym(p).concatstabto(asmoutput);
  721. end;
  722. procedure TStoredSymtable.resetstab(p : TNamedIndexItem);
  723. begin
  724. if tsym(p).typ <> procsym then
  725. tstoredsym(p).isstabwritten:=false;
  726. end;
  727. procedure TStoredSymtable.concattypestab(p : TNamedIndexItem);
  728. begin
  729. if tsym(p).typ = typesym then
  730. begin
  731. tstoredsym(p).isstabwritten:=false;
  732. tstoredsym(p).concatstabto(asmoutput);
  733. end;
  734. end;
  735. function tstoredsymtable.getnewtypecount : word;
  736. begin
  737. getnewtypecount:=pglobaltypecount^;
  738. inc(pglobaltypecount^);
  739. end;
  740. {$endif GDB}
  741. {$ifdef CHAINPROCSYMS}
  742. procedure chainprocsym(p : tsym);
  743. var
  744. storesymtablestack : tsymtable;
  745. srsym : tsym;
  746. srsymtable : tsymtable;
  747. begin
  748. if p.typ=procsym then
  749. begin
  750. storesymtablestack:=symtablestack;
  751. symtablestack:=p.owner.next;
  752. while assigned(symtablestack) do
  753. begin
  754. { search for same procsym in other units }
  755. searchsym(p.name,srsym,srsymtable)
  756. if assigned(srsym) and
  757. (srsym.typ=procsym) then
  758. begin
  759. tprocsym(p).nextprocsym:=tprocsym(srsym);
  760. symtablestack:=storesymtablestack;
  761. exit;
  762. end
  763. else if srsym=nil then
  764. symtablestack:=nil
  765. else
  766. symtablestack:=srsymtable.next;
  767. end;
  768. symtablestack:=storesymtablestack;
  769. end;
  770. end;
  771. {$endif}
  772. procedure tstoredsymtable.chainoperators;
  773. var
  774. p : tprocsym;
  775. t : ttoken;
  776. def : tprocdef;
  777. srsym : tsym;
  778. srsymtable,
  779. storesymtablestack : tsymtable;
  780. begin
  781. storesymtablestack:=symtablestack;
  782. symtablestack:=self;
  783. make_ref:=false;
  784. for t:=first_overloaded to last_overloaded do
  785. begin
  786. p:=nil;
  787. def:=nil;
  788. overloaded_operators[t]:=nil;
  789. { each operator has a unique lowercased internal name PM }
  790. while assigned(symtablestack) do
  791. begin
  792. searchsym(overloaded_names[t],srsym,srsymtable);
  793. if not assigned(srsym) then
  794. begin
  795. if (t=_STARSTAR) then
  796. begin
  797. symtablestack:=systemunit;
  798. searchsym('POWER',srsym,srsymtable);
  799. end;
  800. end;
  801. if assigned(srsym) then
  802. begin
  803. if (srsym.typ<>procsym) then
  804. internalerror(12344321);
  805. if assigned(p) then
  806. begin
  807. {$ifdef CHAINPROCSYMS}
  808. p.nextprocsym:=tprocsym(srsym);
  809. {$endif CHAINPROCSYMS}
  810. def.nextoverloaded:=tprocsym(srsym).definition;
  811. end
  812. else
  813. overloaded_operators[t]:=tprocsym(srsym);
  814. p:=tprocsym(srsym);
  815. def:=p.definition;
  816. while assigned(def.nextoverloaded) and
  817. (def.nextoverloaded.owner=p.owner) do
  818. def:=def.nextoverloaded;
  819. def.nextoverloaded:=nil;
  820. symtablestack:=srsym.owner.next;
  821. end
  822. else
  823. begin
  824. symtablestack:=nil;
  825. {$ifdef CHAINPROCSYMS}
  826. if assigned(p) then
  827. p.nextprocsym:=nil;
  828. {$endif CHAINPROCSYMS}
  829. end;
  830. { search for same procsym in other units }
  831. end;
  832. symtablestack:=self;
  833. end;
  834. make_ref:=true;
  835. symtablestack:=storesymtablestack;
  836. end;
  837. {***********************************************
  838. Process all entries
  839. ***********************************************}
  840. { checks, if all procsyms and methods are defined }
  841. procedure tstoredsymtable.check_forwards;
  842. begin
  843. foreach({$ifdef FPCPROCVAR}@{$endif}check_forward);
  844. end;
  845. procedure tstoredsymtable.checklabels;
  846. begin
  847. foreach({$ifdef FPCPROCVAR}@{$endif}labeldefined);
  848. end;
  849. procedure tstoredsymtable.set_alignment(_alignment : longint);
  850. var
  851. sym : tvarsym;
  852. l : longint;
  853. begin
  854. dataalignment:=_alignment;
  855. if (symtabletype<>parasymtable) then
  856. internalerror(1111);
  857. sym:=tvarsym(symindex.first);
  858. datasize:=0;
  859. { there can be only varsyms }
  860. while assigned(sym) do
  861. begin
  862. l:=sym.getpushsize;
  863. sym.address:=datasize;
  864. datasize:=align(datasize+l,dataalignment);
  865. sym:=tvarsym(sym.indexnext);
  866. end;
  867. end;
  868. procedure tstoredsymtable.allunitsused;
  869. begin
  870. foreach({$ifdef FPCPROCVAR}@{$endif}unitsymbolused);
  871. end;
  872. procedure tstoredsymtable.allsymbolsused;
  873. begin
  874. foreach({$ifdef FPCPROCVAR}@{$endif}varsymbolused);
  875. end;
  876. procedure tstoredsymtable.allprivatesused;
  877. begin
  878. foreach({$ifdef FPCPROCVAR}@{$endif}objectprivatesymbolused);
  879. end;
  880. {$ifdef CHAINPROCSYMS}
  881. procedure tstoredsymtable.chainprocsyms;
  882. begin
  883. foreach({$ifdef FPCPROCVAR}@{$endif}chainprocsym);
  884. end;
  885. {$endif CHAINPROCSYMS}
  886. {$ifdef GDB}
  887. procedure tstoredsymtable.concatstabto(asmlist : taasmoutput);
  888. begin
  889. asmoutput:=asmlist;
  890. if symtabletype in [inlineparasymtable,inlinelocalsymtable] then
  891. foreach({$ifdef FPCPROCVAR}@{$endif}resetstab);
  892. foreach({$ifdef FPCPROCVAR}@{$endif}concatstab);
  893. end;
  894. {$endif}
  895. {****************************************************************************
  896. PPU Writing Helpers
  897. ****************************************************************************}
  898. procedure writesourcefiles;
  899. var
  900. hp : tinputfile;
  901. i,j : longint;
  902. begin
  903. { second write the used source files }
  904. current_ppu^.do_crc:=false;
  905. hp:=current_module.sourcefiles.files;
  906. { write source files directly in good order }
  907. j:=0;
  908. while assigned(hp) do
  909. begin
  910. inc(j);
  911. hp:=hp.ref_next;
  912. end;
  913. while j>0 do
  914. begin
  915. hp:=current_module.sourcefiles.files;
  916. for i:=1 to j-1 do
  917. hp:=hp.ref_next;
  918. current_ppu^.putstring(hp.name^);
  919. dec(j);
  920. end;
  921. current_ppu^.writeentry(ibsourcefiles);
  922. current_ppu^.do_crc:=true;
  923. end;
  924. procedure writeusedunit;
  925. var
  926. hp : tused_unit;
  927. begin
  928. numberunits;
  929. hp:=tused_unit(current_module.used_units.first);
  930. while assigned(hp) do
  931. begin
  932. { implementation units should not change
  933. the CRC PM }
  934. current_ppu^.do_crc:=hp.in_interface;
  935. current_ppu^.putstring(hp.name^);
  936. { the checksum should not affect the crc of this unit ! (PFV) }
  937. current_ppu^.do_crc:=false;
  938. current_ppu^.putlongint(hp.checksum);
  939. current_ppu^.putlongint(hp.interface_checksum);
  940. current_ppu^.putbyte(byte(hp.in_interface));
  941. current_ppu^.do_crc:=true;
  942. hp:=tused_unit(hp.next);
  943. end;
  944. current_ppu^.do_interface_crc:=true;
  945. current_ppu^.writeentry(ibloadunit);
  946. end;
  947. procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  948. var
  949. hcontainer : tlinkcontainer;
  950. s : string;
  951. mask : cardinal;
  952. begin
  953. hcontainer:=TLinkContainer.Create;
  954. while not p.empty do
  955. begin
  956. s:=p.get(mask);
  957. if strippath then
  958. current_ppu^.putstring(SplitFileName(s))
  959. else
  960. current_ppu^.putstring(s);
  961. current_ppu^.putlongint(mask);
  962. hcontainer.add(s,mask);
  963. end;
  964. current_ppu^.writeentry(id);
  965. p.Free;
  966. p:=hcontainer;
  967. end;
  968. procedure writeunitas(const s : string;unittable : tglobalsymtable;only_crc : boolean);
  969. begin
  970. Message1(unit_u_ppu_write,s);
  971. { create unit flags }
  972. with Current_Module do
  973. begin
  974. {$ifdef GDB}
  975. if cs_gdb_dbx in aktglobalswitches then
  976. flags:=flags or uf_has_dbx;
  977. {$endif GDB}
  978. if target_os.endian=endian_big then
  979. flags:=flags or uf_big_endian;
  980. if cs_browser in aktmoduleswitches then
  981. flags:=flags or uf_has_browser;
  982. if cs_local_browser in aktmoduleswitches then
  983. flags:=flags or uf_local_browser;
  984. end;
  985. {$ifdef Test_Double_checksum_write}
  986. If only_crc then
  987. Assign(CRCFile,s+'.INT')
  988. else
  989. Assign(CRCFile,s+'.IMP');
  990. Rewrite(CRCFile);
  991. {$endif def Test_Double_checksum_write}
  992. { open ppufile }
  993. current_ppu:=new(pppufile,init(s));
  994. current_ppu^.crc_only:=only_crc;
  995. if not current_ppu^.create then
  996. Message(unit_f_ppu_cannot_write);
  997. {$ifdef Test_Double_checksum}
  998. if only_crc then
  999. begin
  1000. new(current_ppu^.crc_test);
  1001. new(current_ppu^.crc_test2);
  1002. end
  1003. else
  1004. begin
  1005. current_ppu^.crc_test:=current_module.crc_array;
  1006. current_ppu^.crc_index:=current_module.crc_size;
  1007. current_ppu^.crc_test2:=current_module.crc_array2;
  1008. current_ppu^.crc_index2:=current_module.crc_size2;
  1009. end;
  1010. {$endif def Test_Double_checksum}
  1011. current_ppu^.change_endian:=source_os.endian<>target_os.endian;
  1012. { write symbols and definitions }
  1013. unittable.write;
  1014. { flush to be sure }
  1015. current_ppu^.flush;
  1016. { create and write header }
  1017. current_ppu^.header.size:=current_ppu^.size;
  1018. current_ppu^.header.checksum:=current_ppu^.crc;
  1019. current_ppu^.header.interface_checksum:=current_ppu^.interface_crc;
  1020. current_ppu^.header.compiler:=wordversion;
  1021. current_ppu^.header.cpu:=word(target_cpu);
  1022. current_ppu^.header.target:=word(target_info.target);
  1023. current_ppu^.header.flags:=current_module.flags;
  1024. If not only_crc then
  1025. current_ppu^.writeheader;
  1026. { save crc in current_module also }
  1027. current_module.crc:=current_ppu^.crc;
  1028. current_module.interface_crc:=current_ppu^.interface_crc;
  1029. if only_crc then
  1030. begin
  1031. {$ifdef Test_Double_checksum}
  1032. current_module.crc_array:=current_ppu^.crc_test;
  1033. current_ppu^.crc_test:=nil;
  1034. current_module.crc_size:=current_ppu^.crc_index2;
  1035. current_module.crc_array2:=current_ppu^.crc_test2;
  1036. current_ppu^.crc_test2:=nil;
  1037. current_module.crc_size2:=current_ppu^.crc_index2;
  1038. {$endif def Test_Double_checksum}
  1039. closecurrentppu;
  1040. end;
  1041. {$ifdef Test_Double_checksum_write}
  1042. close(CRCFile);
  1043. {$endif Test_Double_checksum_write}
  1044. end;
  1045. procedure readusedmacros;
  1046. var
  1047. hs : string;
  1048. mac : tmacro;
  1049. was_defined_at_startup,
  1050. was_used : boolean;
  1051. begin
  1052. while not current_ppu^.endofentry do
  1053. begin
  1054. hs:=current_ppu^.getstring;
  1055. was_defined_at_startup:=boolean(current_ppu^.getbyte);
  1056. was_used:=boolean(current_ppu^.getbyte);
  1057. mac:=tmacro(current_scanner.macros.search(hs));
  1058. if assigned(mac) then
  1059. begin
  1060. {$ifndef EXTDEBUG}
  1061. { if we don't have the sources why tell }
  1062. if current_module.sources_avail then
  1063. {$endif ndef EXTDEBUG}
  1064. if (not was_defined_at_startup) and
  1065. was_used and
  1066. mac.defined_at_startup then
  1067. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module.mainsource^);
  1068. end
  1069. else { not assigned }
  1070. if was_defined_at_startup and
  1071. was_used then
  1072. Message2(unit_h_cond_not_set_in_last_compile,hs,current_module.mainsource^);
  1073. end;
  1074. end;
  1075. procedure readsourcefiles;
  1076. var
  1077. temp,hs : string;
  1078. temp_dir : string;
  1079. main_dir : string;
  1080. incfile_found,
  1081. main_found,
  1082. is_main : boolean;
  1083. ppufiletime,
  1084. source_time : longint;
  1085. hp : tinputfile;
  1086. begin
  1087. ppufiletime:=getnamedfiletime(current_module.ppufilename^);
  1088. current_module.sources_avail:=true;
  1089. is_main:=true;
  1090. main_dir:='';
  1091. while not current_ppu^.endofentry do
  1092. begin
  1093. hs:=current_ppu^.getstring;
  1094. temp_dir:='';
  1095. if (current_module.flags and uf_in_library)<>0 then
  1096. begin
  1097. current_module.sources_avail:=false;
  1098. temp:=' library';
  1099. end
  1100. else if pos('Macro ',hs)=1 then
  1101. begin
  1102. { we don't want to find this file }
  1103. { but there is a problem with file indexing !! }
  1104. temp:='';
  1105. end
  1106. else
  1107. begin
  1108. { check the date of the source files }
  1109. Source_Time:=GetNamedFileTime(current_module.path^+hs);
  1110. incfile_found:=false;
  1111. main_found:=false;
  1112. if Source_Time<>-1 then
  1113. hs:=current_module.path^+hs
  1114. else
  1115. if not(is_main) then
  1116. begin
  1117. Source_Time:=GetNamedFileTime(main_dir+hs);
  1118. if Source_Time<>-1 then
  1119. hs:=main_dir+hs;
  1120. end;
  1121. if (Source_Time=-1) then
  1122. begin
  1123. if is_main then
  1124. main_found:=unitsearchpath.FindFile(hs,temp_dir)
  1125. else
  1126. incfile_found:=includesearchpath.FindFile(hs,temp_dir);
  1127. if incfile_found or main_found then
  1128. Source_Time:=GetNamedFileTime(temp_dir);
  1129. end;
  1130. if Source_Time=-1 then
  1131. begin
  1132. current_module.sources_avail:=false;
  1133. temp:=' not found';
  1134. end
  1135. else
  1136. begin
  1137. if main_found then
  1138. main_dir:=temp_dir;
  1139. { time newer? But only allow if the file is not searched
  1140. in the include path (PFV), else you've problems with
  1141. units which use the same includefile names }
  1142. if incfile_found then
  1143. temp:=' found'
  1144. else
  1145. begin
  1146. temp:=' time '+filetimestring(source_time);
  1147. if (source_time>ppufiletime) then
  1148. begin
  1149. current_module.do_compile:=true;
  1150. current_module.recompile_reason:=rr_sourcenewer;
  1151. temp:=temp+' *'
  1152. end;
  1153. end;
  1154. end;
  1155. hp:=tinputfile.create(hs);
  1156. { the indexing is wrong here PM }
  1157. current_module.sourcefiles.register_file(hp);
  1158. end;
  1159. if is_main then
  1160. begin
  1161. stringdispose(current_module.mainsource);
  1162. current_module.mainsource:=stringdup(hs);
  1163. end;
  1164. Message1(unit_u_ppu_source,hs+temp);
  1165. is_main:=false;
  1166. end;
  1167. { check if we want to rebuild every unit, only if the sources are
  1168. available }
  1169. if do_build and current_module.sources_avail then
  1170. begin
  1171. current_module.do_compile:=true;
  1172. current_module.recompile_reason:=rr_build;
  1173. end;
  1174. end;
  1175. procedure readloadunit;
  1176. var
  1177. hs : string;
  1178. intfchecksum,
  1179. checksum : longint;
  1180. in_interface : boolean;
  1181. begin
  1182. while not current_ppu^.endofentry do
  1183. begin
  1184. hs:=current_ppu^.getstring;
  1185. checksum:=current_ppu^.getlongint;
  1186. intfchecksum:=current_ppu^.getlongint;
  1187. in_interface:=(current_ppu^.getbyte<>0);
  1188. current_module.used_units.concat(tused_unit.create_to_load(hs,checksum,intfchecksum,in_interface));
  1189. end;
  1190. end;
  1191. procedure readlinkcontainer(var p:tlinkcontainer);
  1192. var
  1193. s : string;
  1194. m : longint;
  1195. begin
  1196. while not current_ppu^.endofentry do
  1197. begin
  1198. s:=current_ppu^.getstring;
  1199. m:=current_ppu^.getlongint;
  1200. p.add(s,m);
  1201. end;
  1202. end;
  1203. procedure load_interface;
  1204. var
  1205. b : byte;
  1206. newmodulename : string;
  1207. begin
  1208. { read interface part }
  1209. repeat
  1210. b:=current_ppu^.readentry;
  1211. case b of
  1212. ibmodulename :
  1213. begin
  1214. newmodulename:=current_ppu^.getstring;
  1215. if upper(newmodulename)<>current_module.modulename^ then
  1216. Message2(unit_f_unit_name_error,current_module.realmodulename^,newmodulename);
  1217. stringdispose(current_module.modulename);
  1218. stringdispose(current_module.realmodulename);
  1219. current_module.modulename:=stringdup(upper(newmodulename));
  1220. current_module.realmodulename:=stringdup(newmodulename);
  1221. end;
  1222. ibsourcefiles :
  1223. readsourcefiles;
  1224. ibusedmacros :
  1225. readusedmacros;
  1226. ibloadunit :
  1227. readloadunit;
  1228. iblinkunitofiles :
  1229. readlinkcontainer(current_module.LinkUnitOFiles);
  1230. iblinkunitstaticlibs :
  1231. readlinkcontainer(current_module.LinkUnitStaticLibs);
  1232. iblinkunitsharedlibs :
  1233. readlinkcontainer(current_module.LinkUnitSharedLibs);
  1234. iblinkotherofiles :
  1235. readlinkcontainer(current_module.LinkotherOFiles);
  1236. iblinkotherstaticlibs :
  1237. readlinkcontainer(current_module.LinkotherStaticLibs);
  1238. iblinkothersharedlibs :
  1239. readlinkcontainer(current_module.LinkotherSharedLibs);
  1240. ibendinterface :
  1241. break;
  1242. else
  1243. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1244. end;
  1245. until false;
  1246. end;
  1247. {****************************************************************************
  1248. TAbstractRecordSymtable
  1249. ****************************************************************************}
  1250. procedure tabstractrecordsymtable.load;
  1251. var
  1252. storesymtable : tsymtable;
  1253. begin
  1254. storesymtable:=aktrecordsymtable;
  1255. aktrecordsymtable:=self;
  1256. inherited load;
  1257. aktrecordsymtable:=storesymtable;
  1258. end;
  1259. procedure tabstractrecordsymtable.write;
  1260. var
  1261. oldtyp : byte;
  1262. storesymtable : tsymtable;
  1263. begin
  1264. storesymtable:=aktrecordsymtable;
  1265. aktrecordsymtable:=self;
  1266. oldtyp:=current_ppu^.entrytyp;
  1267. current_ppu^.entrytyp:=subentryid;
  1268. { order procsym overloads }
  1269. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1270. inherited write;
  1271. current_ppu^.entrytyp:=oldtyp;
  1272. aktrecordsymtable:=storesymtable;
  1273. end;
  1274. procedure tabstractrecordsymtable.load_browser;
  1275. var
  1276. storesymtable : tsymtable;
  1277. begin
  1278. storesymtable:=aktrecordsymtable;
  1279. aktrecordsymtable:=self;
  1280. inherited load_browser;
  1281. aktrecordsymtable:=storesymtable;
  1282. end;
  1283. procedure tabstractrecordsymtable.write_browser;
  1284. var
  1285. storesymtable : tsymtable;
  1286. begin
  1287. storesymtable:=aktrecordsymtable;
  1288. aktrecordsymtable:=self;
  1289. inherited write_browser;
  1290. aktrecordsymtable:=storesymtable;
  1291. end;
  1292. procedure TStoredSymtable._needs_init_final(p : tnamedindexitem);
  1293. begin
  1294. if (not b_needs_init_final) and
  1295. (tsym(p).typ=varsym) and
  1296. assigned(tvarsym(p).vartype.def) and
  1297. not is_class(tvarsym(p).vartype.def) and
  1298. tstoreddef(tvarsym(p).vartype.def).needs_inittable then
  1299. b_needs_init_final:=true;
  1300. end;
  1301. { returns true, if p contains data which needs init/final code }
  1302. function tstoredsymtable.needs_init_final : boolean;
  1303. begin
  1304. b_needs_init_final:=false;
  1305. foreach({$ifdef FPCPROCVAR}@{$endif}_needs_init_final);
  1306. needs_init_final:=b_needs_init_final;
  1307. end;
  1308. {****************************************************************************
  1309. TRecordSymtable
  1310. ****************************************************************************}
  1311. constructor trecordsymtable.create;
  1312. begin
  1313. inherited create('');
  1314. symtabletype:=recordsymtable;
  1315. end;
  1316. { this procedure is reserved for inserting case variant into
  1317. a record symtable }
  1318. { the offset is the location of the start of the variant
  1319. and datasize and dataalignment corresponds to
  1320. the complete size (see code in pdecl unit) PM }
  1321. procedure trecordsymtable.insert_in(tsymt : tsymtable;offset : longint);
  1322. var
  1323. ps,nps : tvarsym;
  1324. pd,npd : tdef;
  1325. storesize,storealign : longint;
  1326. begin
  1327. storesize:=tsymt.datasize;
  1328. storealign:=tsymt.dataalignment;
  1329. tsymt.datasize:=offset;
  1330. ps:=tvarsym(symindex.first);
  1331. while assigned(ps) do
  1332. begin
  1333. { this is used to insert case variant into the main
  1334. record }
  1335. tsymt.datasize:=ps.address+offset;
  1336. nps:=tvarsym(ps.indexnext);
  1337. symindex.deleteindex(ps);
  1338. ps.left:=nil;
  1339. ps.right:=nil;
  1340. tsymt.insert(ps);
  1341. ps:=nps;
  1342. end;
  1343. pd:=tdef(defindex.first);
  1344. while assigned(pd) do
  1345. begin
  1346. npd:=tdef(pd.indexnext);
  1347. defindex.deleteindex(pd);
  1348. pd.left:=nil;
  1349. pd.right:=nil;
  1350. tsymt.registerdef(pd);
  1351. pd:=npd;
  1352. end;
  1353. tsymt.datasize:=storesize;
  1354. tsymt.dataalignment:=storealign;
  1355. end;
  1356. {****************************************************************************
  1357. TObjectSymtable
  1358. ****************************************************************************}
  1359. constructor tobjectsymtable.create(const n:string);
  1360. begin
  1361. inherited create(n);
  1362. symtabletype:=objectsymtable;
  1363. end;
  1364. procedure tobjectsymtable.insert(sym:tsymentry);
  1365. var
  1366. hsym : tsym;
  1367. begin
  1368. { check for duplicate field id in inherited classes }
  1369. if (sym.typ=varsym) and
  1370. assigned(defowner) and
  1371. (
  1372. not(m_delphi in aktmodeswitches) or
  1373. is_object(tdef(defowner))
  1374. ) then
  1375. begin
  1376. { but private ids can be reused }
  1377. hsym:=search_class_member(tobjectdef(defowner),sym.name);
  1378. if assigned(hsym) and
  1379. (not(sp_private in hsym.symoptions) or
  1380. (hsym.owner.defowner.owner.unitid=0)) then
  1381. begin
  1382. DuplicateSym(hsym);
  1383. exit;
  1384. end;
  1385. end;
  1386. inherited insert(sym);
  1387. end;
  1388. {****************************************************************************
  1389. TAbstractLocalSymtable
  1390. ****************************************************************************}
  1391. procedure tabstractlocalsymtable.load;
  1392. var
  1393. storesymtable : tsymtable;
  1394. begin
  1395. storesymtable:=aktlocalsymtable;
  1396. aktlocalsymtable:=self;
  1397. inherited load;
  1398. aktlocalsymtable:=storesymtable;
  1399. end;
  1400. procedure tabstractlocalsymtable.write;
  1401. var
  1402. oldtyp : byte;
  1403. storesymtable : tsymtable;
  1404. begin
  1405. storesymtable:=aktlocalsymtable;
  1406. aktlocalsymtable:=self;
  1407. oldtyp:=current_ppu^.entrytyp;
  1408. current_ppu^.entrytyp:=subentryid;
  1409. { order procsym overloads }
  1410. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1411. { write definitions }
  1412. writedefs;
  1413. { write symbols }
  1414. writesyms;
  1415. current_ppu^.entrytyp:=oldtyp;
  1416. aktlocalsymtable:=storesymtable;
  1417. end;
  1418. procedure tabstractlocalsymtable.load_browser;
  1419. var
  1420. storesymtable : tsymtable;
  1421. begin
  1422. storesymtable:=aktlocalsymtable;
  1423. aktlocalsymtable:=self;
  1424. inherited load_browser;
  1425. aktlocalsymtable:=storesymtable;
  1426. end;
  1427. procedure tabstractlocalsymtable.write_browser;
  1428. var
  1429. storesymtable : tsymtable;
  1430. begin
  1431. storesymtable:=aktlocalsymtable;
  1432. aktlocalsymtable:=self;
  1433. inherited load_browser;
  1434. aktlocalsymtable:=storesymtable;
  1435. end;
  1436. {****************************************************************************
  1437. TLocalSymtable
  1438. ****************************************************************************}
  1439. constructor tlocalsymtable.create;
  1440. begin
  1441. inherited create('');
  1442. symtabletype:=localsymtable;
  1443. end;
  1444. procedure tlocalsymtable.insert(sym:tsymentry);
  1445. var
  1446. hsym : tsym;
  1447. begin
  1448. if assigned(next) then
  1449. begin
  1450. if (next.symtabletype=parasymtable) then
  1451. begin
  1452. hsym:=tsym(next.search(sym.name));
  1453. if assigned(hsym) then
  1454. begin
  1455. { a parameter and the function can have the same
  1456. name in TP and Delphi, but RESULT not }
  1457. if (m_tp in aktmodeswitches) and
  1458. (sym.typ=funcretsym) and
  1459. not((m_result in aktmodeswitches) and
  1460. (sym.name='RESULT')) then
  1461. sym.name:='hidden'+sym.name
  1462. else
  1463. begin
  1464. DuplicateSym(hsym);
  1465. exit;
  1466. end;
  1467. end;
  1468. end
  1469. else if (current_module.flags and uf_local_browser)=0 then
  1470. internalerror(43789);
  1471. { check for duplicate id in local symtable of methods }
  1472. if assigned(next.next) and
  1473. { funcretsym is allowed !! }
  1474. (sym.typ <> funcretsym) and
  1475. (next.next.symtabletype=objectsymtable) then
  1476. begin
  1477. hsym:=search_class_member(tobjectdef(next.next.defowner),sym.name);
  1478. if assigned(hsym) and
  1479. { private ids can be reused }
  1480. (not(sp_private in hsym.symoptions) or
  1481. (hsym.owner.defowner.owner.symtabletype<>globalsymtable)) then
  1482. begin
  1483. { delphi allows to reuse the names in a class, but not
  1484. in object (tp7 compatible) }
  1485. if not((m_delphi in aktmodeswitches) and
  1486. is_class(tdef(next.next.defowner))) then
  1487. begin
  1488. DuplicateSym(hsym);
  1489. exit;
  1490. end;
  1491. end;
  1492. end;
  1493. end;
  1494. inherited insert(sym);
  1495. end;
  1496. {****************************************************************************
  1497. TParaSymtable
  1498. ****************************************************************************}
  1499. constructor tparasymtable.create;
  1500. begin
  1501. inherited create('');
  1502. symtabletype:=parasymtable;
  1503. dataalignment:=4;
  1504. end;
  1505. procedure tparasymtable.insert(sym:tsymentry);
  1506. var
  1507. hsym : tsym;
  1508. begin
  1509. { check for duplicate id in para symtable of methods }
  1510. if assigned(procinfo^._class) and
  1511. { but not in nested procedures !}
  1512. (not(assigned(procinfo^.parent)) or
  1513. (assigned(procinfo^.parent) and
  1514. not(assigned(procinfo^.parent^._class)))
  1515. ) and
  1516. { funcretsym is allowed !! }
  1517. (sym.typ <> funcretsym) then
  1518. begin
  1519. hsym:=search_class_member(procinfo^._class,sym.name);
  1520. if assigned(hsym) and
  1521. { private ids can be reused }
  1522. (not(sp_private in hsym.symoptions) or
  1523. (hsym.owner.defowner.owner.unitid=0)) then
  1524. begin
  1525. { delphi allows to reuse the names in a class, but not
  1526. in object (tp7 compatible) }
  1527. if not((m_delphi in aktmodeswitches) and
  1528. is_class(procinfo^._class)) then
  1529. begin
  1530. DuplicateSym(hsym);
  1531. exit;
  1532. end;
  1533. end;
  1534. end;
  1535. inherited insert(sym);
  1536. end;
  1537. {****************************************************************************
  1538. TAbstractUnitSymtable
  1539. ****************************************************************************}
  1540. constructor tabstractunitsymtable.create(const n : string);
  1541. begin
  1542. inherited create(n);
  1543. symsearch.usehash;
  1544. {$ifdef GDB}
  1545. { reset GDB things }
  1546. prev_dbx_counter := dbx_counter;
  1547. dbx_counter := nil;
  1548. is_stab_written:=false;
  1549. dbx_count := -1;
  1550. {$endif GDB}
  1551. end;
  1552. procedure tabstractunitsymtable.concattypestabto(asmlist : taasmoutput);
  1553. var prev_dbx_count : plongint;
  1554. begin
  1555. if is_stab_written then
  1556. exit;
  1557. if not assigned(name) then
  1558. name := stringdup('Main_program');
  1559. if (symtabletype = globalsymtable) and
  1560. (current_module.globalsymtable<>self) then
  1561. begin
  1562. unitid:=current_module.unitcount;
  1563. inc(current_module.unitcount);
  1564. end;
  1565. asmList.concat(Tai_asm_comment.Create(strpnew('Begin unit '+name^+' has index '+tostr(unitid))));
  1566. if cs_gdb_dbx in aktglobalswitches then
  1567. begin
  1568. if dbx_count_ok then
  1569. begin
  1570. asmList.concat(Tai_asm_comment.Create(strpnew('"repeated" unit '+name^
  1571. +' has index '+tostr(unitid)+' dbx count = '+tostr(dbx_count))));
  1572. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1573. +tostr(N_EXCL)+',0,0,'+tostr(dbx_count))));
  1574. exit;
  1575. end
  1576. else if (current_module.globalsymtable<>self) then
  1577. begin
  1578. prev_dbx_count := dbx_counter;
  1579. dbx_counter := nil;
  1580. do_count_dbx:=false;
  1581. if (symtabletype = globalsymtable) and (unitid<>0) then
  1582. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1583. dbx_counter := @dbx_count;
  1584. dbx_count:=0;
  1585. do_count_dbx:=assigned(dbx_counter);
  1586. end;
  1587. end;
  1588. asmoutput:=asmlist;
  1589. foreach({$ifdef FPCPROCVAR}@{$endif}concattypestab);
  1590. if cs_gdb_dbx in aktglobalswitches then
  1591. begin
  1592. if (current_module.globalsymtable<>self) then
  1593. begin
  1594. dbx_counter := prev_dbx_count;
  1595. do_count_dbx:=false;
  1596. asmList.concat(Tai_asm_comment.Create(strpnew('End unit '+name^
  1597. +' has index '+tostr(unitid))));
  1598. asmList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'
  1599. +tostr(N_EINCL)+',0,0,0')));
  1600. do_count_dbx:=assigned(dbx_counter);
  1601. dbx_count_ok := {true}false;
  1602. end;
  1603. end;
  1604. is_stab_written:=true;
  1605. end;
  1606. {****************************************************************************
  1607. TStaticSymtable
  1608. ****************************************************************************}
  1609. constructor tstaticsymtable.create(const n : string);
  1610. begin
  1611. inherited create(n);
  1612. symtabletype:=staticsymtable;
  1613. end;
  1614. procedure tstaticsymtable.load;
  1615. begin
  1616. aktstaticsymtable:=self;
  1617. next:=symtablestack;
  1618. symtablestack:=self;
  1619. inherited load;
  1620. { now we can deref the syms and defs }
  1621. deref;
  1622. { restore symtablestack }
  1623. symtablestack:=next;
  1624. end;
  1625. procedure tstaticsymtable.write;
  1626. begin
  1627. aktstaticsymtable:=self;
  1628. { order procsym overloads }
  1629. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1630. inherited write;
  1631. end;
  1632. procedure tstaticsymtable.load_browser;
  1633. begin
  1634. aktstaticsymtable:=self;
  1635. inherited load_browser;
  1636. end;
  1637. procedure tstaticsymtable.write_browser;
  1638. begin
  1639. aktstaticsymtable:=self;
  1640. inherited write_browser;
  1641. end;
  1642. procedure tstaticsymtable.insert(sym:tsymentry);
  1643. var
  1644. hsym : tsym;
  1645. begin
  1646. { also check the global symtable }
  1647. if assigned(next) and
  1648. (next.unitid=0) then
  1649. begin
  1650. hsym:=tsym(next.search(sym.name));
  1651. if assigned(hsym) then
  1652. begin
  1653. DuplicateSym(hsym);
  1654. exit;
  1655. end;
  1656. end;
  1657. inherited insert(sym);
  1658. end;
  1659. {****************************************************************************
  1660. TGlobalSymtable
  1661. ****************************************************************************}
  1662. constructor tglobalsymtable.create(const n : string);
  1663. begin
  1664. inherited create(n);
  1665. symtabletype:=globalsymtable;
  1666. unitid:=0;
  1667. unitsym:=nil;
  1668. {$ifdef GDB}
  1669. if cs_gdb_dbx in aktglobalswitches then
  1670. begin
  1671. dbx_count := 0;
  1672. unittypecount:=1;
  1673. pglobaltypecount := @unittypecount;
  1674. unitid:=current_module.unitcount;
  1675. debugList.concat(Tai_asm_comment.Create(strpnew('Global '+name^+' has index '+tostr(unitid))));
  1676. debugList.concat(Tai_stabs.Create(strpnew('"'+name^+'",'+tostr(N_BINCL)+',0,0,0')));
  1677. inc(current_module.unitcount);
  1678. dbx_count_ok:=false;
  1679. dbx_counter:=@dbx_count;
  1680. do_count_dbx:=true;
  1681. end;
  1682. {$endif GDB}
  1683. end;
  1684. destructor tglobalsymtable.destroy;
  1685. var
  1686. pus : tunitsym;
  1687. begin
  1688. pus:=unitsym;
  1689. while assigned(pus) do
  1690. begin
  1691. unitsym:=pus.prevsym;
  1692. pus.prevsym:=nil;
  1693. pus.unitsymtable:=nil;
  1694. pus:=unitsym;
  1695. end;
  1696. inherited destroy;
  1697. end;
  1698. procedure tglobalsymtable.load;
  1699. var
  1700. {$ifdef GDB}
  1701. storeGlobalTypeCount : pword;
  1702. {$endif GDB}
  1703. b : byte;
  1704. begin
  1705. {$ifdef GDB}
  1706. if cs_gdb_dbx in aktglobalswitches then
  1707. begin
  1708. UnitTypeCount:=1;
  1709. storeGlobalTypeCount:=PGlobalTypeCount;
  1710. PglobalTypeCount:=@UnitTypeCount;
  1711. end;
  1712. {$endif GDB}
  1713. symtablelevel:=0;
  1714. {$ifndef NEWMAP}
  1715. current_module.map^[0]:=self;
  1716. {$else NEWMAP}
  1717. current_module.globalsymtable:=self;
  1718. {$endif NEWMAP}
  1719. next:=symtablestack;
  1720. symtablestack:=self;
  1721. inherited load;
  1722. { now we can deref the syms and defs }
  1723. deref;
  1724. { restore symtablestack }
  1725. symtablestack:=next;
  1726. {$ifdef NEWMAP}
  1727. { necessary for dependencies }
  1728. current_module.globalsymtable:=nil;
  1729. {$endif NEWMAP}
  1730. { dbx count }
  1731. {$ifdef GDB}
  1732. if (current_module.flags and uf_has_dbx)<>0 then
  1733. begin
  1734. b := current_ppu^.readentry;
  1735. if b <> ibdbxcount then
  1736. Message(unit_f_ppu_dbx_count_problem)
  1737. else
  1738. dbx_count := readlong;
  1739. dbx_count_ok := {true}false;
  1740. end
  1741. else
  1742. begin
  1743. dbx_count := -1;
  1744. dbx_count_ok:=false;
  1745. end;
  1746. if cs_gdb_dbx in aktglobalswitches then
  1747. PGlobalTypeCount:=storeGlobalTypeCount;
  1748. is_stab_written:=false;
  1749. {$endif GDB}
  1750. b:=current_ppu^.readentry;
  1751. if b<>ibendimplementation then
  1752. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1753. end;
  1754. procedure tglobalsymtable.write;
  1755. var
  1756. pu : tused_unit;
  1757. begin
  1758. { first the unitname }
  1759. current_ppu^.putstring(current_module.realmodulename^);
  1760. current_ppu^.writeentry(ibmodulename);
  1761. writesourcefiles;
  1762. writeusedmacros;
  1763. writeusedunit;
  1764. { write the objectfiles and libraries that come for this unit,
  1765. preserve the containers becuase they are still needed to load
  1766. the link.res. All doesn't depend on the crc! It doesn't matter
  1767. if a unit is in a .o or .a file }
  1768. current_ppu^.do_crc:=false;
  1769. writelinkcontainer(current_module.linkunitofiles,iblinkunitofiles,true);
  1770. writelinkcontainer(current_module.linkunitstaticlibs,iblinkunitstaticlibs,true);
  1771. writelinkcontainer(current_module.linkunitsharedlibs,iblinkunitsharedlibs,true);
  1772. writelinkcontainer(current_module.linkotherofiles,iblinkotherofiles,false);
  1773. writelinkcontainer(current_module.linkotherstaticlibs,iblinkotherstaticlibs,true);
  1774. writelinkcontainer(current_module.linkothersharedlibs,iblinkothersharedlibs,true);
  1775. current_ppu^.do_crc:=true;
  1776. current_ppu^.writeentry(ibendinterface);
  1777. { order procsym overloads }
  1778. foreach({$ifdef FPCPROCVAR}@{$endif}Order_overloads);
  1779. { write the symtable entries }
  1780. inherited write;
  1781. { all after doesn't affect crc }
  1782. current_ppu^.do_crc:=false;
  1783. { write dbx count }
  1784. {$ifdef GDB}
  1785. if cs_gdb_dbx in aktglobalswitches then
  1786. begin
  1787. {$IfDef EXTDEBUG}
  1788. writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
  1789. {$ENDIF EXTDEBUG}
  1790. current_ppu^.putlongint(dbx_count);
  1791. current_ppu^.writeentry(ibdbxcount);
  1792. end;
  1793. {$endif GDB}
  1794. current_ppu^.writeentry(ibendimplementation);
  1795. { write static symtable
  1796. needed for local debugging of unit functions }
  1797. if ((current_module.flags and uf_local_browser)<>0) and
  1798. assigned(current_module.localsymtable) then
  1799. tstaticsymtable(current_module.localsymtable).write;
  1800. { write all browser section }
  1801. if (current_module.flags and uf_has_browser)<>0 then
  1802. begin
  1803. write_browser;
  1804. pu:=tused_unit(current_module.used_units.first);
  1805. while assigned(pu) do
  1806. begin
  1807. tstoredsymtable(pu.u.globalsymtable).write_browser;
  1808. pu:=tused_unit(pu.next);
  1809. end;
  1810. current_ppu^.writeentry(ibendbrowser);
  1811. end;
  1812. if ((current_module.flags and uf_local_browser)<>0) and
  1813. assigned(current_module.localsymtable) then
  1814. tstaticsymtable(current_module.localsymtable).write_browser;
  1815. { the last entry ibend is written automaticly }
  1816. end;
  1817. procedure tglobalsymtable.load_symtable_refs;
  1818. var
  1819. b : byte;
  1820. unitindex : word;
  1821. begin
  1822. if ((current_module.flags and uf_local_browser)<>0) then
  1823. begin
  1824. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^);
  1825. tstaticsymtable(current_module.localsymtable).load;
  1826. end;
  1827. { load browser }
  1828. if (current_module.flags and uf_has_browser)<>0 then
  1829. begin
  1830. {if not (cs_browser in aktmoduleswitches) then
  1831. current_ppu^.skipuntilentry(ibendbrowser)
  1832. else }
  1833. begin
  1834. load_browser;
  1835. unitindex:=1;
  1836. while assigned(current_module.map^[unitindex]) do
  1837. begin
  1838. {each unit wrote one browser entry }
  1839. load_browser;
  1840. inc(unitindex);
  1841. end;
  1842. b:=current_ppu^.readentry;
  1843. if b<>ibendbrowser then
  1844. Message1(unit_f_ppu_invalid_entry,tostr(b));
  1845. end;
  1846. end;
  1847. if ((current_module.flags and uf_local_browser)<>0) then
  1848. tstaticsymtable(current_module.localsymtable).load_browser;
  1849. end;
  1850. procedure tglobalsymtable.writeusedmacro(p:TNamedIndexItem);
  1851. begin
  1852. if tmacro(p).is_used or tmacro(p).defined_at_startup then
  1853. begin
  1854. current_ppu^.putstring(p.name);
  1855. current_ppu^.putbyte(byte(tmacro(p).defined_at_startup));
  1856. current_ppu^.putbyte(byte(tmacro(p).is_used));
  1857. end;
  1858. end;
  1859. procedure tglobalsymtable.writeusedmacros;
  1860. begin
  1861. current_ppu^.do_crc:=false;
  1862. current_scanner.macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro);
  1863. current_ppu^.writeentry(ibusedmacros);
  1864. current_ppu^.do_crc:=true;
  1865. end;
  1866. {$ifdef GDB}
  1867. function tglobalsymtable.getnewtypecount : word;
  1868. begin
  1869. if not (cs_gdb_dbx in aktglobalswitches) then
  1870. getnewtypecount:=inherited getnewtypecount
  1871. else
  1872. begin
  1873. getnewtypecount:=unittypecount;
  1874. inc(unittypecount);
  1875. end;
  1876. end;
  1877. {$endif}
  1878. {****************************************************************************
  1879. TWITHSYMTABLE
  1880. ****************************************************************************}
  1881. constructor twithsymtable.create(aowner:tdef;asymsearch:TDictionary);
  1882. begin
  1883. inherited create('');
  1884. symtabletype:=withsymtable;
  1885. direct_with:=false;
  1886. withnode:=nil;
  1887. withrefnode:=nil;
  1888. { we don't need the symsearch }
  1889. symsearch.free;
  1890. { set the defaults }
  1891. symsearch:=asymsearch;
  1892. defowner:=aowner;
  1893. end;
  1894. destructor twithsymtable.destroy;
  1895. begin
  1896. symsearch:=nil;
  1897. inherited destroy;
  1898. end;
  1899. procedure twithsymtable.clear;
  1900. begin
  1901. { remove no entry from a withsymtable as it is only a pointer to the
  1902. recorddef or objectdef symtable }
  1903. end;
  1904. {****************************************************************************
  1905. TSTT_ExceptionSymtable
  1906. ****************************************************************************}
  1907. constructor tstt_exceptsymtable.create;
  1908. begin
  1909. inherited create('');
  1910. symtabletype:=stt_exceptsymtable;
  1911. end;
  1912. {*****************************************************************************
  1913. Helper Routines
  1914. *****************************************************************************}
  1915. procedure numberunits;
  1916. var
  1917. counter : longint;
  1918. hp : tused_unit;
  1919. hp1 : tmodule;
  1920. begin
  1921. { Reset all numbers to -1 }
  1922. hp1:=tmodule(loaded_units.first);
  1923. while assigned(hp1) do
  1924. begin
  1925. if assigned(hp1.globalsymtable) then
  1926. tsymtable(hp1.globalsymtable).unitid:=$ffff;
  1927. hp1:=tmodule(hp1.next);
  1928. end;
  1929. { Our own symtable gets unitid 0, for a program there is
  1930. no globalsymtable }
  1931. if assigned(current_module.globalsymtable) then
  1932. tsymtable(current_module.globalsymtable).unitid:=0;
  1933. { number units }
  1934. counter:=1;
  1935. hp:=tused_unit(current_module.used_units.first);
  1936. while assigned(hp) do
  1937. begin
  1938. tsymtable(hp.u.globalsymtable).unitid:=counter;
  1939. inc(counter);
  1940. hp:=tused_unit(hp.next);
  1941. end;
  1942. end;
  1943. function findunitsymtable(st:tsymtable):tsymtable;
  1944. begin
  1945. findunitsymtable:=nil;
  1946. repeat
  1947. if not assigned(st) then
  1948. internalerror(5566561);
  1949. case st.symtabletype of
  1950. localsymtable,
  1951. parasymtable,
  1952. staticsymtable :
  1953. break;
  1954. globalsymtable :
  1955. begin
  1956. findunitsymtable:=st;
  1957. break;
  1958. end;
  1959. objectsymtable,
  1960. recordsymtable :
  1961. st:=st.defowner.owner;
  1962. else
  1963. internalerror(5566562);
  1964. end;
  1965. until false;
  1966. end;
  1967. procedure duplicatesym(sym:tsym);
  1968. var
  1969. st : tsymtable;
  1970. begin
  1971. Message1(sym_e_duplicate_id,sym.realname);
  1972. st:=findunitsymtable(sym.owner);
  1973. with sym.fileinfo do
  1974. begin
  1975. if assigned(st) and (st.unitid<>0) then
  1976. Message2(sym_h_duplicate_id_where,'unit '+st.name^,tostr(line))
  1977. else
  1978. Message2(sym_h_duplicate_id_where,current_module.sourcefiles.get_file_name(fileindex),tostr(line));
  1979. end;
  1980. end;
  1981. procedure identifier_not_found(const s:string);
  1982. begin
  1983. Message1(sym_e_id_not_found,s);
  1984. { show a fatal that you need -S2 or -Sd, but only
  1985. if we just parsed the a token that has m_class }
  1986. if not(m_class in aktmodeswitches) and
  1987. (Upper(s)=pattern) and
  1988. (tokeninfo^[idtoken].keyword=m_class) then
  1989. Message(parser_f_need_objfpc_or_delphi_mode);
  1990. end;
  1991. {*****************************************************************************
  1992. Search
  1993. *****************************************************************************}
  1994. function searchsym(const s : stringid;var srsym:tsym;var srsymtable:tsymtable):boolean;
  1995. var
  1996. speedvalue : cardinal;
  1997. begin
  1998. speedvalue:=getspeedvalue(s);
  1999. srsymtable:=symtablestack;
  2000. while assigned(srsymtable) do
  2001. begin
  2002. srsym:=tsym(srsymtable.speedsearch(s,speedvalue));
  2003. if assigned(srsym) then
  2004. begin
  2005. searchsym:=true;
  2006. exit;
  2007. end
  2008. else
  2009. srsymtable:=srsymtable.next;
  2010. end;
  2011. searchsym:=false;
  2012. end;
  2013. function searchsymonlyin(p : tsymtable;const s : stringid):tsym;
  2014. var
  2015. srsym : tsym;
  2016. begin
  2017. { the caller have to take care if srsym=nil }
  2018. if assigned(p) then
  2019. begin
  2020. srsym:=tsym(p.search(s));
  2021. if assigned(srsym) then
  2022. begin
  2023. searchsymonlyin:=srsym;
  2024. exit;
  2025. end;
  2026. { also check in the local symtbale if it exists }
  2027. if (p=tsymtable(current_module.globalsymtable)) then
  2028. begin
  2029. srsym:=tsym(current_module.localsymtable.search(s));
  2030. if assigned(srsym) then
  2031. begin
  2032. searchsymonlyin:=srsym;
  2033. exit;
  2034. end;
  2035. end
  2036. end;
  2037. searchsymonlyin:=nil;
  2038. end;
  2039. function search_class_member(pd : tobjectdef;const s : string):tsym;
  2040. { searches n in symtable of pd and all anchestors }
  2041. var
  2042. speedvalue : cardinal;
  2043. srsym : tsym;
  2044. begin
  2045. speedvalue:=getspeedvalue(s);
  2046. while assigned(pd) do
  2047. begin
  2048. srsym:=tsym(pd.symtable.speedsearch(s,speedvalue));
  2049. if assigned(srsym) then
  2050. begin
  2051. search_class_member:=srsym;
  2052. exit;
  2053. end;
  2054. pd:=pd.childof;
  2055. end;
  2056. search_class_member:=nil;
  2057. end;
  2058. {*****************************************************************************
  2059. Definition Helpers
  2060. *****************************************************************************}
  2061. procedure globaldef(const s : string;var t:ttype);
  2062. var st : string;
  2063. symt : tsymtable;
  2064. srsym : tsym;
  2065. srsymtable : tsymtable;
  2066. begin
  2067. srsym := nil;
  2068. if pos('.',s) > 0 then
  2069. begin
  2070. st := copy(s,1,pos('.',s)-1);
  2071. searchsym(st,srsym,srsymtable);
  2072. st := copy(s,pos('.',s)+1,255);
  2073. if assigned(srsym) then
  2074. begin
  2075. if srsym.typ = unitsym then
  2076. begin
  2077. symt := tunitsym(srsym).unitsymtable;
  2078. srsym := tsym(symt.search(st));
  2079. end else srsym := nil;
  2080. end;
  2081. end else st := s;
  2082. if srsym = nil then
  2083. searchsym(st,srsym,srsymtable);
  2084. if srsym = nil then
  2085. srsym:=searchsymonlyin(systemunit,st);
  2086. if (not assigned(srsym)) or
  2087. (srsym.typ<>typesym) then
  2088. begin
  2089. Message(type_e_type_id_expected);
  2090. t:=generrortype;
  2091. exit;
  2092. end;
  2093. t := ttypesym(srsym).restype;
  2094. end;
  2095. {****************************************************************************
  2096. Object Helpers
  2097. ****************************************************************************}
  2098. var
  2099. _defaultprop : tpropertysym;
  2100. procedure tstoredsymtable.testfordefaultproperty(p : TNamedIndexItem);
  2101. begin
  2102. if (tsym(p).typ=propertysym) and
  2103. (ppo_defaultproperty in tpropertysym(p).propoptions) then
  2104. _defaultprop:=tpropertysym(p);
  2105. end;
  2106. function search_default_property(pd : tobjectdef) : tpropertysym;
  2107. { returns the default property of a class, searches also anchestors }
  2108. begin
  2109. _defaultprop:=nil;
  2110. while assigned(pd) do
  2111. begin
  2112. pd.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}tstoredsymtable(pd.symtable).testfordefaultproperty);
  2113. if assigned(_defaultprop) then
  2114. break;
  2115. pd:=pd.childof;
  2116. end;
  2117. search_default_property:=_defaultprop;
  2118. end;
  2119. {$ifdef UNITALIASES}
  2120. {****************************************************************************
  2121. TUNIT_ALIAS
  2122. ****************************************************************************}
  2123. constructor tunit_alias.create(const n:string);
  2124. var
  2125. i : longint;
  2126. begin
  2127. i:=pos('=',n);
  2128. if i=0 then
  2129. fail;
  2130. inherited createname(Copy(n,1,i-1));
  2131. newname:=stringdup(Copy(n,i+1,255));
  2132. end;
  2133. destructor tunit_alias.destroy;
  2134. begin
  2135. stringdispose(newname);
  2136. inherited destroy;
  2137. end;
  2138. procedure addunitalias(const n:string);
  2139. begin
  2140. unitaliases^.insert(tunit_alias,init(Upper(n))));
  2141. end;
  2142. function getunitalias(const n:string):string;
  2143. var
  2144. p : punit_alias;
  2145. begin
  2146. p:=punit_alias(unitaliases^.search(Upper(n)));
  2147. if assigned(p) then
  2148. getunitalias:=punit_alias(p).newname^
  2149. else
  2150. getunitalias:=n;
  2151. end;
  2152. {$endif UNITALIASES}
  2153. {****************************************************************************
  2154. Symtable Stack
  2155. ****************************************************************************}
  2156. procedure dellexlevel;
  2157. var
  2158. p : tsymtable;
  2159. begin
  2160. p:=symtablestack;
  2161. symtablestack:=p.next;
  2162. { symbol tables of unit interfaces are never disposed }
  2163. { this is handle by the unit unitm }
  2164. if not(p.symtabletype in [globalsymtable,stt_exceptsymtable]) then
  2165. p.free;
  2166. end;
  2167. procedure RestoreUnitSyms;
  2168. var
  2169. p : tsymtable;
  2170. begin
  2171. p:=symtablestack;
  2172. while assigned(p) do
  2173. begin
  2174. if (p.symtabletype=globalsymtable) and
  2175. assigned(tglobalsymtable(p).unitsym) and
  2176. ((tglobalsymtable(p).unitsym.owner=current_module.globalsymtable) or
  2177. (tglobalsymtable(p).unitsym.owner=current_module.localsymtable)) then
  2178. tglobalsymtable(p).unitsym.restoreunitsym;
  2179. p:=p.next;
  2180. end;
  2181. end;
  2182. {$ifdef DEBUG}
  2183. procedure test_symtablestack;
  2184. var
  2185. p : tsymtable;
  2186. i : longint;
  2187. begin
  2188. p:=symtablestack;
  2189. i:=0;
  2190. while assigned(p) do
  2191. begin
  2192. inc(i);
  2193. p:=p.next;
  2194. if i>500 then
  2195. Message(sym_f_internal_error_in_symtablestack);
  2196. end;
  2197. end;
  2198. procedure list_symtablestack;
  2199. var
  2200. p : tsymtable;
  2201. i : longint;
  2202. begin
  2203. p:=symtablestack;
  2204. i:=0;
  2205. while assigned(p) do
  2206. begin
  2207. inc(i);
  2208. writeln(i,' ',p.name^);
  2209. p:=p.next;
  2210. if i>500 then
  2211. Message(sym_f_internal_error_in_symtablestack);
  2212. end;
  2213. end;
  2214. {$endif DEBUG}
  2215. {****************************************************************************
  2216. Init/Done Symtable
  2217. ****************************************************************************}
  2218. procedure InitSymtable;
  2219. var
  2220. token : ttoken;
  2221. begin
  2222. { Reset symbolstack }
  2223. registerdef:=false;
  2224. read_member:=false;
  2225. symtablestack:=nil;
  2226. systemunit:=nil;
  2227. {$ifdef GDB}
  2228. firstglobaldef:=nil;
  2229. lastglobaldef:=nil;
  2230. globaltypecount:=1;
  2231. pglobaltypecount:=@globaltypecount;
  2232. {$endif GDB}
  2233. { create error syms and def }
  2234. generrorsym:=terrorsym.create;
  2235. generrortype.setdef(terrordef.create);
  2236. {$ifdef UNITALIASES}
  2237. { unit aliases }
  2238. unitaliases:=tdictionary.create;
  2239. {$endif}
  2240. for token:=first_overloaded to last_overloaded do
  2241. overloaded_operators[token]:=nil;
  2242. end;
  2243. procedure DoneSymtable;
  2244. begin
  2245. generrorsym.free;
  2246. generrortype.def.free;
  2247. {$ifdef UNITALIASES}
  2248. unitaliases.free;
  2249. {$endif}
  2250. end;
  2251. end.
  2252. {
  2253. $Log$
  2254. Revision 1.33 2001-04-13 20:05:15 peter
  2255. * better check for globalsymtable
  2256. Revision 1.32 2001/04/13 18:08:37 peter
  2257. * scanner object to class
  2258. Revision 1.31 2001/04/13 01:22:16 peter
  2259. * symtable change to classes
  2260. * range check generation and errors fixed, make cycle DEBUG=1 works
  2261. * memory leaks fixed
  2262. Revision 1.30 2001/04/02 21:20:35 peter
  2263. * resulttype rewrite
  2264. Revision 1.29 2001/03/22 00:10:58 florian
  2265. + basic variant type support in the compiler
  2266. Revision 1.28 2001/03/13 18:45:07 peter
  2267. * fixed some memory leaks
  2268. Revision 1.27 2001/03/11 22:58:51 peter
  2269. * getsym redesign, removed the globals srsym,srsymtable
  2270. Revision 1.26 2001/02/21 19:37:19 peter
  2271. * moved deref to be done after loading of implementation units. prederef
  2272. is still done directly after loading of symbols and definitions.
  2273. Revision 1.25 2001/02/20 21:41:16 peter
  2274. * new fixfilename, findfile for unix. Look first for lowercase, then
  2275. NormalCase and last for UPPERCASE names.
  2276. Revision 1.24 2001/01/08 21:40:27 peter
  2277. * fixed crash with unsupported token overloading
  2278. Revision 1.23 2000/12/25 00:07:30 peter
  2279. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2280. tlinkedlist objects)
  2281. Revision 1.22 2000/12/23 19:50:09 peter
  2282. * fixed mem leak with withsymtable
  2283. Revision 1.21 2000/12/10 20:25:32 peter
  2284. * fixed missing typecast
  2285. Revision 1.20 2000/12/10 14:14:51 florian
  2286. * fixed web bug 1203: class fields can be now redefined
  2287. in Delphi mode though I don't like this :/
  2288. Revision 1.19 2000/11/30 22:16:49 florian
  2289. * moved to i386
  2290. Revision 1.18 2000/11/29 00:30:42 florian
  2291. * unused units removed from uses clause
  2292. * some changes for widestrings
  2293. Revision 1.17 2000/11/28 00:28:07 pierre
  2294. * stabs fixing
  2295. Revision 1.1.2.8 2000/11/17 11:14:37 pierre
  2296. * one more class stabs fix
  2297. Revision 1.16 2000/11/12 22:17:47 peter
  2298. * some realname updates for messages
  2299. Revision 1.15 2000/11/06 15:54:15 florian
  2300. * fixed two bugs to get make cycle work, but it's not enough
  2301. Revision 1.14 2000/11/04 14:25:22 florian
  2302. + merged Attila's changes for interfaces, not tested yet
  2303. Revision 1.13 2000/11/01 23:04:38 peter
  2304. * tprocdef.fullprocname added for better casesensitve writing of
  2305. procedures
  2306. Revision 1.12 2000/10/31 22:02:52 peter
  2307. * symtable splitted, no real code changes
  2308. Revision 1.1.2.7 2000/10/16 19:43:04 pierre
  2309. * trying to correct class stabss once more
  2310. Revision 1.11 2000/10/15 07:47:53 peter
  2311. * unit names and procedure names are stored mixed case
  2312. Revision 1.10 2000/10/14 10:14:53 peter
  2313. * moehrendorf oct 2000 rewrite
  2314. Revision 1.9 2000/10/01 19:48:25 peter
  2315. * lot of compile updates for cg11
  2316. Revision 1.8 2000/09/24 15:06:29 peter
  2317. * use defines.inc
  2318. Revision 1.7 2000/08/27 16:11:54 peter
  2319. * moved some util functions from globals,cobjects to cutils
  2320. * splitted files into finput,fmodule
  2321. Revision 1.6 2000/08/21 11:27:45 pierre
  2322. * fix the stabs problems
  2323. Revision 1.5 2000/08/20 14:58:41 peter
  2324. * give fatal if objfpc/delphi mode things are found (merged)
  2325. Revision 1.1.2.6 2000/08/20 14:56:46 peter
  2326. * give fatal if objfpc/delphi mode things are found
  2327. Revision 1.4 2000/08/16 18:33:54 peter
  2328. * splitted namedobjectitem.next into indexnext and listnext so it
  2329. can be used in both lists
  2330. * don't allow "word = word" type definitions (merged)
  2331. Revision 1.3 2000/08/08 19:28:57 peter
  2332. * memdebug/memory patches (merged)
  2333. * only once illegal directive (merged)
  2334. }