fmodule.pas 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. This unit implements the first loading and searching of the modules
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit fmodule;
  18. {$i fpcdefs.inc}
  19. {$ifdef go32v2}
  20. {$define shortasmprefix}
  21. {$endif}
  22. {$ifdef watcom}
  23. {$define shortasmprefix}
  24. {$endif}
  25. {$ifdef atari}
  26. {$define shortasmprefix}
  27. {$endif}
  28. {$ifdef OS2}
  29. { Allthough OS/2 supports long filenames I play it safe and
  30. use 8.3 filenames, because this allows the compiler to run
  31. on a FAT partition. (DM) }
  32. {$define shortasmprefix}
  33. {$endif}
  34. interface
  35. uses
  36. cutils,cclasses,cfileutl,
  37. globtype,finput,ogbase,fpkg,
  38. symbase,symsym,
  39. wpobase,
  40. aasmbase,aasmdata;
  41. const
  42. UNSPECIFIED_LIBRARY_NAME = '<none>';
  43. type
  44. trecompile_reason = (rr_unknown,
  45. rr_noppu,rr_sourcenewer,rr_build,rr_crcchanged
  46. );
  47. { unit options }
  48. tmoduleoption = (mo_none,
  49. mo_hint_deprecated,
  50. mo_hint_platform,
  51. mo_hint_library,
  52. mo_hint_unimplemented,
  53. mo_hint_experimental,
  54. mo_has_deprecated_msg
  55. );
  56. tmoduleoptions = set of tmoduleoption;
  57. tlinkcontaineritem=class(tlinkedlistitem)
  58. public
  59. data : TPathStr;
  60. needlink : cardinal;
  61. constructor Create(const s:TPathStr;m:cardinal);
  62. end;
  63. tlinkcontainer=class(tlinkedlist)
  64. procedure add(const s : TPathStr;m:cardinal);
  65. function get(var m:cardinal) : TPathStr;
  66. function getusemask(mask:cardinal) : TPathStr;
  67. function find(const s:TPathStr):boolean;
  68. end;
  69. tmodule = class;
  70. tused_unit = class;
  71. tunitmaprec = record
  72. u : tmodule;
  73. { number of references }
  74. refs : longint;
  75. { index in the derefmap }
  76. derefidx : longint;
  77. end;
  78. punitmap = ^tunitmaprec;
  79. tderefmaprec = record
  80. u : tmodule;
  81. { modulename, used during ppu load }
  82. modulename : pshortstring;
  83. end;
  84. pderefmap = ^tderefmaprec;
  85. { tmodule }
  86. tmodule = class(tmodulebase)
  87. private
  88. FImportLibraryList : TFPHashObjectList;
  89. public
  90. do_reload, { force reloading of the unit }
  91. do_compile, { need to compile the sources }
  92. sources_avail, { if all sources are reachable }
  93. interface_compiled, { if the interface section has been parsed/compiled/loaded }
  94. is_dbginfo_written,
  95. is_unit,
  96. in_interface, { processing the implementation part? }
  97. { allow global settings }
  98. in_global : boolean;
  99. { Whether a mode switch is still allowed at this point in the parsing.}
  100. mode_switch_allowed,
  101. { generate pic helper which loads eip in ecx (for leave procedures) }
  102. requires_ecx_pic_helper,
  103. { generate pic helper which loads eip in ebx (for non leave procedures) }
  104. requires_ebx_pic_helper : boolean;
  105. interface_only: boolean; { interface-only macpas unit; flag does not need saving/restoring to ppu }
  106. mainfilepos : tfileposinfo;
  107. recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
  108. crc,
  109. interface_crc,
  110. indirect_crc : cardinal;
  111. headerflags : cardinal; { the PPU header flags }
  112. longversion : cardinal; { longer version than what fits in the ppu header }
  113. moduleflags : tmoduleflags; { ppu flags that do not need to be known by just reading the ppu header }
  114. islibrary : boolean; { if it is a library (win32 dll) }
  115. IsPackage : boolean;
  116. moduleid : longint;
  117. unitmap : punitmap; { mapping of all used units }
  118. unitmapsize : longint; { number of units in the map }
  119. derefmap : pderefmap; { mapping of all units needed for deref }
  120. derefmapcnt : longint; { number of units in the map }
  121. derefmapsize : longint; { number of units in the map }
  122. derefdataintflen : longint;
  123. derefdata : tdynamicarray;
  124. checkforwarddefs,
  125. deflist,
  126. symlist : TFPObjectList;
  127. ptrdefs : THashSet; { list of pointerdefs created in this module so we can reuse them (not saved/restored) }
  128. arraydefs : THashSet; { list of single-element-arraydefs created in this module so we can reuse them (not saved/restored) }
  129. procaddrdefs : THashSet; { list of procvardefs created when getting the address of a procdef (not saved/restored) }
  130. {$ifdef llvm}
  131. llvmdefs : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
  132. llvmusedsyms : TFPObjectList; { a list of asmsymbols and their defs that need to be added to llvm.used (so they're not removed by llvm optimisation passes nor by the linker) }
  133. llvmcompilerusedsyms : TFPObjectList; { a list of asmsymbols and their defs that need to be added to llvm.compiler.used (so they're not removed by llvm optimisation passes) }
  134. llvminitprocs,
  135. llvmfiniprocs : TFPList;
  136. llvmmetadatastrings: TFPHashList; { metadata strings (mapping string -> superregister) }
  137. {$endif llvm}
  138. ansistrdef : tobject; { an ansistring def redefined for the current module }
  139. wpoinfo : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
  140. globalsymtable, { pointer to the global symtable of this unit }
  141. localsymtable : TSymtable;{ pointer to the local symtable of this unit }
  142. globalmacrosymtable, { pointer to the global macro symtable of this unit }
  143. localmacrosymtable : TSymtable;{ pointer to the local macro symtable of this unit }
  144. scanner : TObject; { scanner object used }
  145. procinfo : TObject; { current procedure being compiled }
  146. asmdata : TObject; { Assembler data }
  147. asmprefix : pshortstring; { prefix for the smartlink asmfiles }
  148. publicasmsyms : TFPHashObjectList; { contains the assembler symbols which need to be exported from a package }
  149. externasmsyms : TFPHashObjectList; { contains the assembler symbols which are imported from another unit }
  150. unitimportsyms : tfpobjectlist; { list of symbols that are imported from other units }
  151. debuginfo : TObject;
  152. loaded_from : tmodule;
  153. _exports : tlinkedlist;
  154. dllscannerinputlist : TFPHashList;
  155. resourcefiles,
  156. linkorderedsymbols : TCmdStrList;
  157. linkunitofiles,
  158. linkunitstaticlibs,
  159. linkunitsharedlibs,
  160. linkotherofiles, { objects,libs loaded from the source }
  161. linkothersharedlibs, { using $L or $LINKLIB or import lib (for linux) }
  162. linkotherstaticlibs,
  163. linkotherframeworks : tlinkcontainer;
  164. mainname : pshortstring; { alternate name for "main" procedure }
  165. package : tpackage;
  166. used_units : tlinkedlist;
  167. dependent_units : tlinkedlist;
  168. localunitsearchpath, { local searchpaths }
  169. localobjectsearchpath,
  170. localincludesearchpath,
  171. locallibrarysearchpath,
  172. localframeworksearchpath : TSearchPathList;
  173. moduleoptions: tmoduleoptions;
  174. deprecatedmsg: pshortstring;
  175. { contains a list of types that are extended by helper types; the key is
  176. the full name of the type and the data is a TFPObjectList of
  177. tobjectdef instances (the helper defs) }
  178. extendeddefs: TFPHashObjectList;
  179. { contains a list of the current topmost non-generic symbol for a
  180. typename of which at least one generic exists; the key is the
  181. non-generic typename and the data is a TFPObjectList of tgenericdummyentry
  182. instances whereby the last one is the current top most one }
  183. genericdummysyms: TFPHashObjectList;
  184. { contains a list of specializations for which the method bodies need
  185. to be generated }
  186. pendingspecializations : TFPHashObjectList;
  187. { list of attributes that are used and thus need their construction
  188. functions generated }
  189. used_rtti_attrs: tfpobjectlist;
  190. { this contains a list of units that needs to be waited for until the
  191. unit can be finished (code generated, etc.); this is needed to handle
  192. specializations in circular unit usages correctly }
  193. waitingforunit: tfpobjectlist;
  194. { this contains a list of all units that are waiting for this unit to be
  195. finished }
  196. waitingunits: tfpobjectlist;
  197. finishstate: pointer;
  198. globalstate: pointer;
  199. namespace: pshortstring; { for JVM target: corresponds to Java package name }
  200. { for targets that initialise typed constants via explicit assignments
  201. instead of by generating an initialised data section (holds typed
  202. constant assignments at the module level; does not have to be saved
  203. into the ppu file, because translated into code during compilation)
  204. -- actual type: tnode (but fmodule should not depend on node) }
  205. tcinitcode : tobject;
  206. {create creates a new module which name is stored in 's'. LoadedFrom
  207. points to the module calling it. It is nil for the first compiled
  208. module. This allow inheritence of all path lists. MUST pay attention
  209. to that when creating link.res!!!!(mazen)}
  210. constructor create(LoadedFrom:TModule;const amodulename: string; const afilename:TPathStr;_is_unit:boolean);
  211. destructor destroy;override;
  212. procedure reset;virtual;
  213. procedure adddependency(callermodule:tmodule);
  214. procedure flagdependent(callermodule:tmodule);
  215. procedure addimportedsym(sym:TSymEntry);
  216. function addusedunit(hp:tmodule;inuses:boolean;usym:tunitsym):tused_unit;
  217. procedure updatemaps;
  218. function derefidx_unit(id:longint):longint;
  219. function resolve_unit(id:longint):tmodule;
  220. procedure allunitsused;
  221. procedure end_of_parsing;virtual;
  222. procedure setmodulename(const s:string);
  223. procedure AddExternalImport(const libname,symname,symmangledname:string;OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
  224. procedure add_public_asmsym(sym:TAsmSymbol);
  225. procedure add_public_asmsym(const name:TSymStr;bind:TAsmsymbind;typ:Tasmsymtype);
  226. procedure add_extern_asmsym(sym:TAsmSymbol);
  227. procedure add_extern_asmsym(const name:TSymStr;bind:TAsmsymbind;typ:Tasmsymtype);
  228. property ImportLibraryList : TFPHashObjectList read FImportLibraryList;
  229. end;
  230. tused_unit = class(tlinkedlistitem)
  231. checksum,
  232. interface_checksum,
  233. indirect_checksum: cardinal;
  234. in_uses,
  235. in_interface : boolean;
  236. u : tmodule;
  237. unitsym : tunitsym;
  238. constructor create(_u : tmodule;intface,inuses:boolean;usym:tunitsym);
  239. procedure check_hints;
  240. end;
  241. tdependent_unit = class(tlinkedlistitem)
  242. u : tmodule;
  243. constructor create(_u : tmodule);
  244. end;
  245. var
  246. main_module : tmodule; { Main module of the program }
  247. current_module : tmodule; { Current module which is compiled or loaded }
  248. compiled_module : tmodule; { Current module which is compiled }
  249. usedunits : tlinkedlist; { Used units for this program }
  250. loaded_units : tlinkedlist; { All loaded units }
  251. unloaded_units : tlinkedlist; { Units removed from loaded_units, to be freed }
  252. SmartLinkOFiles : TCmdStrList; { List of .o files which are generated,
  253. used to delete them after linking }
  254. procedure set_current_module(p:tmodule);
  255. function get_module(moduleindex : longint) : tmodule;
  256. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  257. procedure addloadedunit(hp:tmodule);
  258. function find_module_from_symtable(st:tsymtable):tmodule;
  259. implementation
  260. uses
  261. SysUtils,globals,
  262. verbose,systems,
  263. scanner,ppu,dbgbase,
  264. procinfo,symdef;
  265. {$ifdef MEMDEBUG}
  266. var
  267. memsymtable : TMemDebug;
  268. {$endif}
  269. {*****************************************************************************
  270. Global Functions
  271. *****************************************************************************}
  272. function find_module_from_symtable(st:tsymtable):tmodule;
  273. var
  274. hp : tmodule;
  275. begin
  276. result:=nil;
  277. hp:=tmodule(loaded_units.first);
  278. while assigned(hp) do
  279. begin
  280. if (hp.moduleid=st.moduleid) then
  281. begin
  282. result:=hp;
  283. exit;
  284. end;
  285. hp:=tmodule(hp.next);
  286. end;
  287. end;
  288. procedure set_current_module(p:tmodule);
  289. begin
  290. { save the state of the scanner }
  291. if assigned(current_scanner) then
  292. current_scanner.tempcloseinputfile;
  293. { set new module }
  294. current_module:=p;
  295. { restore previous module settings }
  296. Fillchar(current_filepos,0,sizeof(current_filepos));
  297. if assigned(current_module) then
  298. begin
  299. current_asmdata:=tasmdata(current_module.asmdata);
  300. current_debuginfo:=tdebuginfo(current_module.debuginfo);
  301. { restore scanner and file positions }
  302. current_scanner:=tscannerfile(current_module.scanner);
  303. if assigned(current_scanner) then
  304. begin
  305. current_scanner.tempopeninputfile;
  306. current_scanner.gettokenpos;
  307. parser_current_file:=current_scanner.inputfile.name;
  308. end
  309. else
  310. begin
  311. current_filepos.moduleindex:=current_module.unit_index;
  312. parser_current_file:='';
  313. end;
  314. end
  315. else
  316. begin
  317. current_asmdata:=nil;
  318. current_scanner:=nil;
  319. current_debuginfo:=nil;
  320. end;
  321. end;
  322. function get_module(moduleindex : longint) : tmodule;
  323. var
  324. hp : tmodule;
  325. begin
  326. result:=nil;
  327. if moduleindex=0 then
  328. exit;
  329. result:=current_module;
  330. if not(assigned(loaded_units)) then
  331. exit;
  332. hp:=tmodule(loaded_units.first);
  333. while assigned(hp) and (hp.unit_index<>moduleindex) do
  334. hp:=tmodule(hp.next);
  335. result:=hp;
  336. end;
  337. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  338. var
  339. hp : tmodule;
  340. begin
  341. hp:=get_module(moduleindex);
  342. if assigned(hp) then
  343. get_source_file:=hp.sourcefiles.get_file(fileindex)
  344. else
  345. get_source_file:=nil;
  346. end;
  347. procedure addloadedunit(hp:tmodule);
  348. begin
  349. hp.moduleid:=loaded_units.count;
  350. loaded_units.concat(hp);
  351. end;
  352. {****************************************************************************
  353. TLinkContainerItem
  354. ****************************************************************************}
  355. constructor TLinkContainerItem.Create(const s:TPathStr;m:cardinal);
  356. begin
  357. inherited Create;
  358. data:=s;
  359. needlink:=m;
  360. end;
  361. {****************************************************************************
  362. TLinkContainer
  363. ****************************************************************************}
  364. procedure TLinkContainer.add(const s : TPathStr;m:cardinal);
  365. begin
  366. inherited concat(TLinkContainerItem.Create(s,m));
  367. end;
  368. function TLinkContainer.get(var m:cardinal) : TPathStr;
  369. var
  370. p : tlinkcontaineritem;
  371. begin
  372. p:=tlinkcontaineritem(inherited getfirst);
  373. if p=nil then
  374. begin
  375. get:='';
  376. m:=0;
  377. end
  378. else
  379. begin
  380. get:=p.data;
  381. m:=p.needlink;
  382. p.free;
  383. end;
  384. end;
  385. function TLinkContainer.getusemask(mask:cardinal) : TPathStr;
  386. var
  387. p : tlinkcontaineritem;
  388. found : boolean;
  389. begin
  390. found:=false;
  391. repeat
  392. p:=tlinkcontaineritem(inherited getfirst);
  393. if p=nil then
  394. begin
  395. getusemask:='';
  396. exit;
  397. end;
  398. getusemask:=p.data;
  399. found:=(p.needlink and mask)<>0;
  400. p.free;
  401. until found;
  402. end;
  403. function TLinkContainer.find(const s:TPathStr):boolean;
  404. var
  405. newnode : tlinkcontaineritem;
  406. begin
  407. find:=false;
  408. newnode:=tlinkcontaineritem(First);
  409. while assigned(newnode) do
  410. begin
  411. if newnode.data=s then
  412. begin
  413. find:=true;
  414. exit;
  415. end;
  416. newnode:=tlinkcontaineritem(newnode.next);
  417. end;
  418. end;
  419. {****************************************************************************
  420. TUSED_UNIT
  421. ****************************************************************************}
  422. constructor tused_unit.create(_u : tmodule;intface,inuses:boolean;usym:tunitsym);
  423. begin
  424. u:=_u;
  425. in_interface:=intface;
  426. in_uses:=inuses;
  427. unitsym:=usym;
  428. if _u.state=ms_compiled then
  429. begin
  430. checksum:=u.crc;
  431. interface_checksum:=u.interface_crc;
  432. indirect_checksum:=u.indirect_crc;
  433. end
  434. else
  435. begin
  436. checksum:=0;
  437. interface_checksum:=0;
  438. indirect_checksum:=0;
  439. end;
  440. end;
  441. procedure tused_unit.check_hints;
  442. var
  443. uname: pshortstring;
  444. begin
  445. uname:=u.realmodulename;
  446. if mo_hint_deprecated in u.moduleoptions then
  447. if (mo_has_deprecated_msg in u.moduleoptions) and (u.deprecatedmsg <> nil) then
  448. MessagePos2(unitsym.fileinfo,sym_w_deprecated_unit_with_msg,uname^,u.deprecatedmsg^)
  449. else
  450. MessagePos1(unitsym.fileinfo,sym_w_deprecated_unit,uname^);
  451. if mo_hint_experimental in u.moduleoptions then
  452. MessagePos1(unitsym.fileinfo,sym_w_experimental_unit,uname^);
  453. if mo_hint_platform in u.moduleoptions then
  454. MessagePos1(unitsym.fileinfo,sym_w_non_portable_unit,uname^);
  455. if mo_hint_library in u.moduleoptions then
  456. MessagePos1(unitsym.fileinfo,sym_w_library_unit,uname^);
  457. if mo_hint_unimplemented in u.moduleoptions then
  458. MessagePos1(unitsym.fileinfo,sym_w_non_implemented_unit,uname^);
  459. end;
  460. {****************************************************************************
  461. TDENPENDENT_UNIT
  462. ****************************************************************************}
  463. constructor tdependent_unit.create(_u : tmodule);
  464. begin
  465. u:=_u;
  466. end;
  467. {****************************************************************************
  468. TMODULE
  469. ****************************************************************************}
  470. constructor tmodule.create(LoadedFrom:TModule;const amodulename: string; const afilename:TPathStr;_is_unit:boolean);
  471. var
  472. n:string;
  473. fn:TPathStr;
  474. begin
  475. if amodulename='' then
  476. n:=ChangeFileExt(ExtractFileName(afilename),'')
  477. else
  478. n:=amodulename;
  479. if afilename='' then
  480. fn:=amodulename
  481. else
  482. fn:=afilename;
  483. { Programs have the name 'Program' to don't conflict with dup id's }
  484. if _is_unit then
  485. inherited create(amodulename)
  486. else
  487. inherited create('Program');
  488. mainsource:=fn;
  489. { Dos has the famous 8.3 limit :( }
  490. {$ifdef shortasmprefix}
  491. asmprefix:=stringdup(FixFileName('as'));
  492. {$else}
  493. asmprefix:=stringdup(FixFileName(n));
  494. {$endif}
  495. setfilename(fn,true);
  496. localunitsearchpath:=TSearchPathList.Create;
  497. localobjectsearchpath:=TSearchPathList.Create;
  498. localincludesearchpath:=TSearchPathList.Create;
  499. locallibrarysearchpath:=TSearchPathList.Create;
  500. localframeworksearchpath:=TSearchPathList.Create;
  501. used_units:=TLinkedList.Create;
  502. dependent_units:=TLinkedList.Create;
  503. resourcefiles:=TCmdStrList.Create;
  504. linkorderedsymbols:=TCmdStrList.Create;
  505. linkunitofiles:=TLinkContainer.Create;
  506. linkunitstaticlibs:=TLinkContainer.Create;
  507. linkunitsharedlibs:=TLinkContainer.Create;
  508. linkotherofiles:=TLinkContainer.Create;
  509. linkotherstaticlibs:=TLinkContainer.Create;
  510. linkothersharedlibs:=TLinkContainer.Create;
  511. linkotherframeworks:=TLinkContainer.Create;
  512. mainname:=nil;
  513. FImportLibraryList:=TFPHashObjectList.Create(true);
  514. crc:=0;
  515. interface_crc:=0;
  516. indirect_crc:=0;
  517. headerflags:=0;
  518. longversion:=0;
  519. moduleflags:=[];
  520. scanner:=nil;
  521. unitmap:=nil;
  522. unitmapsize:=0;
  523. derefmap:=nil;
  524. derefmapsize:=0;
  525. derefmapcnt:=0;
  526. derefdata:=TDynamicArray.Create(1024);
  527. derefdataintflen:=0;
  528. deflist:=TFPObjectList.Create(false);
  529. symlist:=TFPObjectList.Create(false);
  530. ptrdefs:=THashSet.Create(64,true,false);
  531. arraydefs:=THashSet.Create(64,true,false);
  532. procaddrdefs:=THashSet.Create(64,true,false);
  533. {$ifdef llvm}
  534. llvmdefs:=THashSet.Create(64,true,false);
  535. llvmusedsyms:=TFPObjectList.Create(true);
  536. llvmcompilerusedsyms:=TFPObjectList.Create(true);
  537. llvminitprocs:=TFPList.Create;
  538. llvmfiniprocs:=TFPList.Create;
  539. llvmmetadatastrings:=TFPHashList.Create;
  540. {$endif llvm}
  541. ansistrdef:=nil;
  542. wpoinfo:=nil;
  543. checkforwarddefs:=TFPObjectList.Create(false);
  544. extendeddefs:=TFPHashObjectList.Create(true);
  545. genericdummysyms:=tfphashobjectlist.create(true);
  546. pendingspecializations:=tfphashobjectlist.create(false);
  547. waitingforunit:=tfpobjectlist.create(false);
  548. waitingunits:=tfpobjectlist.create(false);
  549. used_rtti_attrs:=tfpobjectlist.create(false);
  550. globalsymtable:=nil;
  551. localsymtable:=nil;
  552. globalmacrosymtable:=nil;
  553. localmacrosymtable:=nil;
  554. loaded_from:=LoadedFrom;
  555. do_reload:=false;
  556. do_compile:=false;
  557. sources_avail:=true;
  558. mainfilepos.line:=0;
  559. mainfilepos.column:=0;
  560. mainfilepos.fileindex:=0;
  561. recompile_reason:=rr_unknown;
  562. in_interface:=true;
  563. in_global:=true;
  564. is_unit:=_is_unit;
  565. islibrary:=false;
  566. ispackage:=false;
  567. is_dbginfo_written:=false;
  568. mode_switch_allowed:= true;
  569. moduleoptions:=[];
  570. deprecatedmsg:=nil;
  571. namespace:=nil;
  572. tcinitcode:=nil;
  573. _exports:=TLinkedList.Create;
  574. dllscannerinputlist:=TFPHashList.Create;
  575. asmdata:=casmdata.create(modulename);
  576. unitimportsyms:=TFPObjectList.Create(false);
  577. publicasmsyms:=TFPHashObjectList.Create(true);
  578. externasmsyms:=TFPHashObjectList.Create(true);
  579. InitDebugInfo(self,false);
  580. end;
  581. destructor tmodule.Destroy;
  582. var
  583. i : longint;
  584. current_debuginfo_reset : boolean;
  585. begin
  586. if assigned(unitmap) then
  587. freemem(unitmap);
  588. if assigned(derefmap) then
  589. begin
  590. for i:=0 to derefmapcnt-1 do
  591. stringdispose(derefmap[i].modulename);
  592. freemem(derefmap);
  593. end;
  594. if assigned(_exports) then
  595. _exports.free;
  596. if assigned(dllscannerinputlist) then
  597. dllscannerinputlist.free;
  598. if assigned(scanner) then
  599. begin
  600. { also update current_scanner if it was pointing
  601. to this module }
  602. if current_scanner=tscannerfile(scanner) then
  603. current_scanner:=nil;
  604. tscannerfile(scanner).free;
  605. end;
  606. if assigned(asmdata) then
  607. begin
  608. if current_asmdata=asmdata then
  609. current_asmdata:=nil;
  610. asmdata.free;
  611. end;
  612. if assigned(procinfo) then
  613. begin
  614. if current_procinfo=tprocinfo(procinfo) then
  615. begin
  616. current_procinfo:=nil;
  617. current_structdef:=nil;
  618. current_genericdef:=nil;
  619. current_specializedef:=nil;
  620. end;
  621. { release procinfo tree }
  622. tprocinfo(procinfo).destroy_tree;
  623. end;
  624. DoneDebugInfo(self,current_debuginfo_reset);
  625. used_units.free;
  626. dependent_units.free;
  627. resourcefiles.Free;
  628. linkorderedsymbols.Free;
  629. linkunitofiles.Free;
  630. linkunitstaticlibs.Free;
  631. linkunitsharedlibs.Free;
  632. linkotherofiles.Free;
  633. linkotherstaticlibs.Free;
  634. linkothersharedlibs.Free;
  635. linkotherframeworks.Free;
  636. stringdispose(mainname);
  637. externasmsyms.Free;
  638. publicasmsyms.Free;
  639. unitimportsyms.Free;
  640. FImportLibraryList.Free;
  641. extendeddefs.Free;
  642. genericdummysyms.free;
  643. pendingspecializations.free;
  644. waitingforunit.free;
  645. waitingunits.free;
  646. used_rtti_attrs.free;
  647. stringdispose(asmprefix);
  648. stringdispose(deprecatedmsg);
  649. stringdispose(namespace);
  650. tcinitcode.free;
  651. localunitsearchpath.Free;
  652. localobjectsearchpath.free;
  653. localincludesearchpath.free;
  654. locallibrarysearchpath.free;
  655. localframeworksearchpath.free;
  656. {$ifdef MEMDEBUG}
  657. memsymtable.start;
  658. {$endif}
  659. derefdata.free;
  660. deflist.free;
  661. symlist.free;
  662. ptrdefs.free;
  663. arraydefs.free;
  664. procaddrdefs.free;
  665. {$ifdef llvm}
  666. llvmdefs.free;
  667. llvmusedsyms.free;
  668. llvmcompilerusedsyms.free;
  669. llvminitprocs.free;
  670. llvmfiniprocs.free;
  671. llvmmetadatastrings.free;
  672. {$endif llvm}
  673. ansistrdef:=nil;
  674. wpoinfo.free;
  675. checkforwarddefs.free;
  676. globalsymtable.free;
  677. localsymtable.free;
  678. globalmacrosymtable.free;
  679. localmacrosymtable.free;
  680. {$ifdef MEMDEBUG}
  681. memsymtable.stop;
  682. {$endif}
  683. inherited Destroy;
  684. end;
  685. procedure tmodule.reset;
  686. var
  687. i : longint;
  688. current_debuginfo_reset : boolean;
  689. begin
  690. if assigned(scanner) then
  691. begin
  692. { also update current_scanner if it was pointing
  693. to this module }
  694. if current_scanner=tscannerfile(scanner) then
  695. current_scanner:=nil;
  696. tscannerfile(scanner).free;
  697. scanner:=nil;
  698. end;
  699. if assigned(procinfo) then
  700. begin
  701. if current_procinfo=tprocinfo(procinfo) then
  702. begin
  703. current_procinfo:=nil;
  704. current_structdef:=nil;
  705. current_genericdef:=nil;
  706. current_specializedef:=nil;
  707. end;
  708. { release procinfo tree }
  709. tprocinfo(procinfo).destroy_tree;
  710. end;
  711. if assigned(asmdata) then
  712. begin
  713. if current_asmdata=asmdata then
  714. current_asmdata:=nil;
  715. asmdata.free;
  716. asmdata:=nil;
  717. end;
  718. DoneDebugInfo(self,current_debuginfo_reset);
  719. globalsymtable.free;
  720. globalsymtable:=nil;
  721. localsymtable.free;
  722. localsymtable:=nil;
  723. globalmacrosymtable.free;
  724. globalmacrosymtable:=nil;
  725. localmacrosymtable.free;
  726. localmacrosymtable:=nil;
  727. deflist.free;
  728. deflist:=TFPObjectList.Create(false);
  729. symlist.free;
  730. symlist:=TFPObjectList.Create(false);
  731. ptrdefs.free;
  732. ptrdefs:=THashSet.Create(64,true,false);
  733. arraydefs.free;
  734. arraydefs:=THashSet.Create(64,true,false);
  735. procaddrdefs.free;
  736. procaddrdefs:=THashSet.Create(64,true,false);
  737. {$ifdef llvm}
  738. llvmdefs.free;
  739. llvmdefs:=THashSet.Create(64,true,false);
  740. llvmusedsyms.free;
  741. llvmusedsyms:=TFPObjectList.Create(true);
  742. llvmcompilerusedsyms.free;
  743. llvmcompilerusedsyms:=TFPObjectList.Create(true);
  744. llvminitprocs.free;
  745. llvminitprocs:=TFPList.Create;
  746. llvmfiniprocs.free;
  747. llvmfiniprocs:=TFPList.Create;
  748. llvmmetadatastrings.free;
  749. llvmmetadatastrings:=TFPHashList.Create;
  750. {$endif llvm}
  751. wpoinfo.free;
  752. wpoinfo:=nil;
  753. checkforwarddefs.free;
  754. checkforwarddefs:=TFPObjectList.Create(false);
  755. publicasmsyms.free;
  756. publicasmsyms:=TFPHashObjectList.Create(true);
  757. externasmsyms.free;
  758. externasmsyms:=TFPHashObjectList.Create(true);
  759. unitimportsyms.free;
  760. unitimportsyms:=TFPObjectList.Create(false);
  761. derefdata.free;
  762. derefdata:=TDynamicArray.Create(1024);
  763. if assigned(unitmap) then
  764. begin
  765. freemem(unitmap);
  766. unitmap:=nil;
  767. end;
  768. if assigned(derefmap) then
  769. begin
  770. for i:=0 to derefmapcnt-1 do
  771. stringdispose(derefmap[i].modulename);
  772. freemem(derefmap);
  773. derefmap:=nil;
  774. end;
  775. unitmapsize:=0;
  776. derefmapsize:=0;
  777. derefmapcnt:=0;
  778. derefdataintflen:=0;
  779. sourcefiles.free;
  780. sourcefiles:=tinputfilemanager.create;
  781. asmdata:=casmdata.create(modulename);
  782. InitDebugInfo(self,current_debuginfo_reset);
  783. _exports.free;
  784. _exports:=tlinkedlist.create;
  785. dllscannerinputlist.free;
  786. dllscannerinputlist:=TFPHashList.create;
  787. used_units.free;
  788. used_units:=TLinkedList.Create;
  789. dependent_units.free;
  790. dependent_units:=TLinkedList.Create;
  791. resourcefiles.Free;
  792. resourcefiles:=TCmdStrList.Create;
  793. linkorderedsymbols.Free;
  794. linkorderedsymbols:=TCmdStrList.Create;;
  795. pendingspecializations.free;
  796. pendingspecializations:=tfphashobjectlist.create(false);
  797. if assigned(waitingforunit) and
  798. (waitingforunit.count<>0) then
  799. internalerror(2016070501);
  800. waitingforunit.free;
  801. waitingforunit:=tfpobjectlist.create(false);;
  802. linkunitofiles.Free;
  803. linkunitofiles:=TLinkContainer.Create;
  804. linkunitstaticlibs.Free;
  805. linkunitstaticlibs:=TLinkContainer.Create;
  806. linkunitsharedlibs.Free;
  807. linkunitsharedlibs:=TLinkContainer.Create;
  808. linkotherofiles.Free;
  809. linkotherofiles:=TLinkContainer.Create;
  810. linkotherstaticlibs.Free;
  811. linkotherstaticlibs:=TLinkContainer.Create;
  812. linkothersharedlibs.Free;
  813. linkothersharedlibs:=TLinkContainer.Create;
  814. linkotherframeworks.Free;
  815. linkotherframeworks:=TLinkContainer.Create;
  816. stringdispose(mainname);
  817. FImportLibraryList.Free;
  818. FImportLibraryList:=TFPHashObjectList.Create;
  819. do_compile:=false;
  820. do_reload:=false;
  821. interface_compiled:=false;
  822. in_interface:=true;
  823. in_global:=true;
  824. mode_switch_allowed:=true;
  825. stringdispose(deprecatedmsg);
  826. stringdispose(namespace);
  827. tcinitcode.free;
  828. tcinitcode:=nil;
  829. localunitsearchpath.Free;
  830. localunitsearchpath:=TSearchPathList.Create;
  831. localobjectsearchpath.free;
  832. localobjectsearchpath:=TSearchPathList.Create;
  833. localincludesearchpath.free;
  834. localincludesearchpath:=TSearchPathList.Create;
  835. locallibrarysearchpath.free;
  836. locallibrarysearchpath:=TSearchPathList.Create;
  837. localframeworksearchpath.free;
  838. localframeworksearchpath:=TSearchPathList.Create;
  839. moduleoptions:=[];
  840. is_dbginfo_written:=false;
  841. crc:=0;
  842. interface_crc:=0;
  843. indirect_crc:=0;
  844. headerflags:=0;
  845. longversion:=0;
  846. moduleflags:=[];
  847. mainfilepos.line:=0;
  848. mainfilepos.column:=0;
  849. mainfilepos.fileindex:=0;
  850. recompile_reason:=rr_unknown;
  851. {
  852. The following fields should not
  853. be reset:
  854. mainsource
  855. state
  856. loaded_from
  857. sources_avail
  858. }
  859. end;
  860. procedure tmodule.adddependency(callermodule:tmodule);
  861. begin
  862. { This is not needed for programs }
  863. if not callermodule.is_unit then
  864. exit;
  865. Message2(unit_u_add_depend_to,callermodule.modulename^,modulename^);
  866. dependent_units.concat(tdependent_unit.create(callermodule));
  867. end;
  868. procedure tmodule.flagdependent(callermodule:tmodule);
  869. var
  870. pm : tdependent_unit;
  871. begin
  872. { flag all units that depend on this unit for reloading }
  873. pm:=tdependent_unit(current_module.dependent_units.first);
  874. while assigned(pm) do
  875. begin
  876. { We do not have to reload the unit that wants to load
  877. this unit, unless this unit is already compiled during
  878. the loading }
  879. if (pm.u=callermodule) and
  880. (pm.u.state<>ms_compiled) then
  881. Message1(unit_u_no_reload_is_caller,pm.u.modulename^)
  882. else
  883. if pm.u.state=ms_second_compile then
  884. Message1(unit_u_no_reload_in_second_compile,pm.u.modulename^)
  885. else
  886. begin
  887. pm.u.do_reload:=true;
  888. Message1(unit_u_flag_for_reload,pm.u.modulename^);
  889. end;
  890. pm:=tdependent_unit(pm.next);
  891. end;
  892. end;
  893. procedure tmodule.addimportedsym(sym:TSymEntry);
  894. begin
  895. if unitimportsyms.IndexOf(sym)<0 then
  896. unitimportsyms.Add(sym);
  897. end;
  898. function tmodule.addusedunit(hp:tmodule;inuses:boolean;usym:tunitsym):tused_unit;
  899. var
  900. pu : tused_unit;
  901. begin
  902. pu:=tused_unit.create(hp,in_interface,inuses,usym);
  903. used_units.concat(pu);
  904. addusedunit:=pu;
  905. end;
  906. procedure tmodule.updatemaps;
  907. var
  908. oldmapsize : longint;
  909. hp : tmodule;
  910. i : longint;
  911. begin
  912. { Extend unitmap }
  913. oldmapsize:=unitmapsize;
  914. unitmapsize:=loaded_units.count;
  915. reallocmem(unitmap,unitmapsize*sizeof(tunitmaprec));
  916. fillchar(unitmap[oldmapsize],(unitmapsize-oldmapsize)*sizeof(tunitmaprec),0);
  917. { Extend Derefmap }
  918. oldmapsize:=derefmapsize;
  919. derefmapsize:=loaded_units.count;
  920. reallocmem(derefmap,derefmapsize*sizeof(tderefmaprec));
  921. fillchar(derefmap[oldmapsize],(derefmapsize-oldmapsize)*sizeof(tderefmaprec),0);
  922. { Add all units to unitmap }
  923. hp:=tmodule(loaded_units.first);
  924. i:=0;
  925. while assigned(hp) do
  926. begin
  927. if hp.moduleid>=unitmapsize then
  928. internalerror(200501151);
  929. { Verify old entries }
  930. if (i<oldmapsize) then
  931. begin
  932. if (hp.moduleid<>i) or
  933. (unitmap[hp.moduleid].u<>hp) then
  934. internalerror(200501156);
  935. end
  936. else
  937. begin
  938. unitmap[hp.moduleid].u:=hp;
  939. unitmap[hp.moduleid].derefidx:=-1;
  940. end;
  941. inc(i);
  942. hp:=tmodule(hp.next);
  943. end;
  944. end;
  945. function tmodule.derefidx_unit(id:longint):longint;
  946. begin
  947. if id>=unitmapsize then
  948. internalerror(2005011511);
  949. if unitmap[id].derefidx=-1 then
  950. begin
  951. unitmap[id].derefidx:=derefmapcnt;
  952. inc(derefmapcnt);
  953. derefmap[unitmap[id].derefidx].u:=unitmap[id].u;
  954. end;
  955. if unitmap[id].derefidx>=derefmapsize then
  956. internalerror(2005011514);
  957. result:=unitmap[id].derefidx;
  958. end;
  959. function tmodule.resolve_unit(id:longint):tmodule;
  960. var
  961. hp : tmodule;
  962. begin
  963. if id>=derefmapsize then
  964. internalerror(200306231);
  965. result:=derefmap[id].u;
  966. if not assigned(result) then
  967. begin
  968. if not assigned(derefmap[id].modulename) or
  969. (derefmap[id].modulename^='') then
  970. internalerror(200501159);
  971. hp:=tmodule(loaded_units.first);
  972. while assigned(hp) do
  973. begin
  974. { only check for units. The main program is also
  975. as a unit in the loaded_units list. We simply need
  976. to ignore this entry (PFV) }
  977. if hp.is_unit and
  978. (hp.modulename^=derefmap[id].modulename^) then
  979. break;
  980. hp:=tmodule(hp.next);
  981. end;
  982. if not assigned(hp) then
  983. internalerror(2005011510);
  984. derefmap[id].u:=hp;
  985. result:=hp;
  986. end;
  987. end;
  988. procedure tmodule.allunitsused;
  989. var
  990. pu : tused_unit;
  991. begin
  992. pu:=tused_unit(used_units.first);
  993. while assigned(pu) do
  994. begin
  995. if assigned(pu.u.globalsymtable) then
  996. begin
  997. if unitmap[pu.u.moduleid].u<>pu.u then
  998. internalerror(200501157);
  999. { Give a note when the unit is not referenced, skip
  1000. this is for units with an initialization/finalization }
  1001. if (unitmap[pu.u.moduleid].refs=0) and
  1002. pu.in_uses and
  1003. ((pu.u.moduleflags * [mf_init,mf_finalize])=[]) then
  1004. CGMessagePos2(pu.unitsym.fileinfo,sym_n_unit_not_used,pu.u.realmodulename^,realmodulename^);
  1005. end;
  1006. pu:=tused_unit(pu.next);
  1007. end;
  1008. end;
  1009. procedure tmodule.end_of_parsing;
  1010. begin
  1011. { free asmdata }
  1012. if assigned(asmdata) then
  1013. begin
  1014. asmdata.free;
  1015. asmdata:=nil;
  1016. end;
  1017. { free scanner }
  1018. if assigned(scanner) then
  1019. begin
  1020. if current_scanner=tscannerfile(scanner) then
  1021. current_scanner:=nil;
  1022. tscannerfile(scanner).free;
  1023. scanner:=nil;
  1024. end;
  1025. { free symtable stack }
  1026. if assigned(symtablestack) then
  1027. begin
  1028. symtablestack.free;
  1029. symtablestack:=nil;
  1030. end;
  1031. if assigned(macrosymtablestack) then
  1032. begin
  1033. macrosymtablestack.free;
  1034. macrosymtablestack:=nil;
  1035. end;
  1036. waitingforunit.free;
  1037. waitingforunit:=nil;
  1038. localmacrosymtable.free;
  1039. localmacrosymtable:=nil;
  1040. ptrdefs.free;
  1041. ptrdefs:=nil;
  1042. arraydefs.free;
  1043. arraydefs:=nil;
  1044. procaddrdefs.free;
  1045. procaddrdefs:=nil;
  1046. {$ifdef llvm}
  1047. llvmdefs.free;
  1048. llvmdefs:=nil;
  1049. {$endif llvm}
  1050. checkforwarddefs.free;
  1051. checkforwarddefs:=nil;
  1052. tcinitcode.free;
  1053. tcinitcode:=nil;
  1054. localunitsearchpath.free;
  1055. localunitsearchpath:=nil;
  1056. localobjectsearchpath.free;
  1057. localobjectsearchpath:=nil;
  1058. localincludesearchpath.free;
  1059. localincludesearchpath:=nil;
  1060. locallibrarysearchpath.free;
  1061. locallibrarysearchpath:=nil;
  1062. localframeworksearchpath.free;
  1063. localframeworksearchpath:=nil;
  1064. end;
  1065. procedure tmodule.setmodulename(const s:string);
  1066. begin
  1067. stringdispose(modulename);
  1068. stringdispose(realmodulename);
  1069. modulename:=stringdup(upper(s));
  1070. realmodulename:=stringdup(s);
  1071. { also update asmlibrary names }
  1072. current_asmdata.name:=modulename;
  1073. end;
  1074. procedure TModule.AddExternalImport(const libname,symname,symmangledname:string;
  1075. OrdNr: longint;isvar:boolean;ImportByOrdinalOnly:boolean);
  1076. var
  1077. ImportLibrary,OtherIL : TImportLibrary;
  1078. ImportSymbol : TImportSymbol;
  1079. i : longint;
  1080. begin
  1081. ImportLibrary:=TImportLibrary(ImportLibraryList.Find(libname));
  1082. if not assigned(ImportLibrary) then
  1083. ImportLibrary:=TImportLibrary.Create(ImportLibraryList,libname);
  1084. ImportSymbol:=TImportSymbol(ImportLibrary.ImportSymbolList.Find(symname));
  1085. if not assigned(ImportSymbol) then
  1086. begin
  1087. { Check that the same name does not exist in another library }
  1088. { If it does and the same mangled name is used, issue a warning }
  1089. if ImportLibraryList.Count>1 then
  1090. for i:=0 To ImportLibraryList.Count-1 do
  1091. begin
  1092. OtherIL:=TImportLibrary(ImportLibraryList.Items[i]);
  1093. ImportSymbol:=TImportSymbol(OtherIL.ImportSymbolList.Find(symname));
  1094. if assigned(ImportSymbol) then
  1095. begin
  1096. if ImportSymbol.MangledName=symmangledname then
  1097. begin
  1098. CGMessage3(sym_w_library_overload,symname,libname,OtherIL.Name);
  1099. break;
  1100. end;
  1101. end;
  1102. end;
  1103. if not ImportByOrdinalOnly then
  1104. { negative ordinal number indicates import by name with ordinal number as hint }
  1105. OrdNr:=-OrdNr;
  1106. ImportSymbol:=TImportSymbol.Create(ImportLibrary.ImportSymbolList,
  1107. symname,symmangledname,OrdNr,isvar);
  1108. end;
  1109. end;
  1110. procedure tmodule.add_public_asmsym(sym:TAsmSymbol);
  1111. begin
  1112. add_public_asmsym(sym.name,sym.bind,sym.typ);
  1113. end;
  1114. procedure tmodule.add_public_asmsym(const name:TSymStr;bind:TAsmsymbind;typ:Tasmsymtype);
  1115. var
  1116. sym : tasmsymbol;
  1117. begin
  1118. { ToDo: check for AB_GLOBAL, AB_EXTERNAL? }
  1119. sym:=tasmsymbol(publicasmsyms.find(name));
  1120. if assigned(sym) then
  1121. begin
  1122. if (sym.bind<>bind) or (sym.typ<>typ) then
  1123. internalerror(2016070101);
  1124. exit;
  1125. end;
  1126. tasmsymbol.create(publicasmsyms,name,bind,typ);
  1127. end;
  1128. procedure tmodule.add_extern_asmsym(sym:TAsmSymbol);
  1129. begin
  1130. add_extern_asmsym(sym.name,sym.bind,sym.typ);
  1131. end;
  1132. procedure tmodule.add_extern_asmsym(const name:TSymStr;bind:TAsmsymbind;typ:Tasmsymtype);
  1133. var
  1134. sym : tasmsymbol;
  1135. begin
  1136. { ToDo: check for AB_EXTERNAL? }
  1137. sym:=tasmsymbol(externasmsyms.find(name));
  1138. if assigned(sym) then
  1139. begin
  1140. if (sym.bind<>bind) or (sym.typ<>typ) then
  1141. internalerror(2016070102);
  1142. exit;
  1143. end;
  1144. tasmsymbol.create(externasmsyms,name,bind,typ);
  1145. end;
  1146. initialization
  1147. {$ifdef MEMDEBUG}
  1148. memsymtable:=TMemDebug.create('Symtables');
  1149. memsymtable.stop;
  1150. {$endif MEMDEBUG}
  1151. finalization
  1152. {$ifdef MEMDEBUG}
  1153. memsymtable.free;
  1154. {$endif MEMDEBUG}
  1155. end.