fmodule.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit implements the first loading and searching of the modules
  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 fmodule;
  19. {$i fpcdefs.inc}
  20. {$ifdef go32v2}
  21. {$define shortasmprefix}
  22. {$endif}
  23. {$ifdef watcom}
  24. {$define shortasmprefix}
  25. {$endif}
  26. {$ifdef tos}
  27. {$define shortasmprefix}
  28. {$endif}
  29. {$ifdef OS2}
  30. { Allthough OS/2 supports long filenames I play it safe and
  31. use 8.3 filenames, because this allows the compiler to run
  32. on a FAT partition. (DM) }
  33. {$define shortasmprefix}
  34. {$endif}
  35. interface
  36. uses
  37. cutils,cclasses,
  38. globals,finput,
  39. symbase,symsym,aasmbase;
  40. type
  41. trecompile_reason = (rr_unknown,
  42. rr_noppu,rr_sourcenewer,rr_build,rr_crcchanged
  43. );
  44. TExternalsItem=class(TLinkedListItem)
  45. public
  46. found : longbool;
  47. data : pstring;
  48. constructor Create(const s:string);
  49. Destructor Destroy;override;
  50. end;
  51. tlinkcontaineritem=class(tlinkedlistitem)
  52. public
  53. data : pstring;
  54. needlink : cardinal;
  55. constructor Create(const s:string;m:cardinal);
  56. destructor Destroy;override;
  57. end;
  58. tlinkcontainer=class(tlinkedlist)
  59. procedure add(const s : string;m:cardinal);
  60. function get(var m:cardinal) : string;
  61. function getusemask(mask:cardinal) : string;
  62. function find(const s:string):boolean;
  63. end;
  64. tmodule = class;
  65. tused_unit = class;
  66. tunitmaprec = record
  67. u : tmodule;
  68. { number of references }
  69. refs : longint;
  70. { index in the derefmap }
  71. derefidx : longint;
  72. end;
  73. punitmap = ^tunitmaprec;
  74. tderefmaprec = record
  75. u : tmodule;
  76. { modulename, used during ppu load }
  77. modulename : pstring;
  78. end;
  79. pderefmap = ^tderefmaprec;
  80. tmodule = class(tmodulebase)
  81. do_reload, { force reloading of the unit }
  82. do_compile, { need to compile the sources }
  83. sources_avail, { if all sources are reachable }
  84. interface_compiled, { if the interface section has been parsed/compiled/loaded }
  85. is_stab_written,
  86. is_reset,
  87. is_unit,
  88. in_interface, { processing the implementation part? }
  89. in_global : boolean; { allow global settings }
  90. mode_switch_allowed : boolean; { Whether a mode switch is still allowed at this point in the parsing.}
  91. mainfilepos : tfileposinfo;
  92. recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
  93. crc,
  94. interface_crc : cardinal;
  95. flags : cardinal; { the PPU flags }
  96. islibrary : boolean; { if it is a library (win32 dll) }
  97. moduleid : longint;
  98. unitmap : punitmap; { mapping of all used units }
  99. unitmapsize : longint; { number of units in the map }
  100. derefmap : pderefmap; { mapping of all units needed for deref }
  101. derefmapcnt : longint; { number of units in the map }
  102. derefmapsize : longint; { number of units in the map }
  103. derefdataintflen : longint;
  104. derefdata : tdynamicarray;
  105. globalsymtable, { pointer to the global symtable of this unit }
  106. localsymtable : tsymtable;{ pointer to the local symtable of this unit }
  107. globalmacrosymtable, { pointer to the global macro symtable of this unit }
  108. localmacrosymtable : tsymtable;{ pointer to the local macro symtable of this unit }
  109. scanner : pointer; { scanner object used }
  110. procinfo : pointer; { current procedure being compiled }
  111. loaded_from : tmodule;
  112. uses_imports : boolean; { Set if the module imports from DLL's.}
  113. imports : tlinkedlist;
  114. _exports : tlinkedlist;
  115. externals : tlinkedlist; {Only for DLL scanners by using Unix-style $LINKLIB }
  116. resourcefiles : tstringlist;
  117. linkunitofiles,
  118. linkunitstaticlibs,
  119. linkunitsharedlibs,
  120. linkotherofiles, { objects,libs loaded from the source }
  121. linkothersharedlibs, { using $L or $LINKLIB or import lib (for linux) }
  122. linkotherstaticlibs : tlinkcontainer;
  123. used_units : tlinkedlist;
  124. dependent_units : tlinkedlist;
  125. localunitsearchpath, { local searchpaths }
  126. localobjectsearchpath,
  127. localincludesearchpath,
  128. locallibrarysearchpath : TSearchPathList;
  129. asmprefix : pstring; { prefix for the smartlink asmfiles }
  130. librarydata : tasmlibrarydata; { librarydata for this module }
  131. {create creates a new module which name is stored in 's'. LoadedFrom
  132. points to the module calling it. It is nil for the first compiled
  133. module. This allow inheritence of all path lists. MUST pay attention
  134. to that when creating link.res!!!!(mazen)}
  135. constructor create(LoadedFrom:TModule;const s:string;_is_unit:boolean);
  136. destructor destroy;override;
  137. procedure reset;virtual;
  138. procedure adddependency(callermodule:tmodule);
  139. procedure flagdependent(callermodule:tmodule);
  140. function addusedunit(hp:tmodule;inuses:boolean;usym:tunitsym):tused_unit;
  141. procedure updatemaps;
  142. function derefidx_unit(id:longint):longint;
  143. function resolve_unit(id:longint):tmodule;
  144. procedure allunitsused;
  145. procedure setmodulename(const s:string);
  146. end;
  147. tused_unit = class(tlinkedlistitem)
  148. checksum,
  149. interface_checksum : cardinal;
  150. in_uses,
  151. in_interface : boolean;
  152. u : tmodule;
  153. unitsym : tunitsym;
  154. constructor create(_u : tmodule;intface,inuses:boolean;usym:tunitsym);
  155. end;
  156. tdependent_unit = class(tlinkedlistitem)
  157. u : tmodule;
  158. constructor create(_u : tmodule);
  159. end;
  160. var
  161. main_module : tmodule; { Main module of the program }
  162. current_module : tmodule; { Current module which is compiled or loaded }
  163. compiled_module : tmodule; { Current module which is compiled }
  164. usedunits : tlinkedlist; { Used units for this program }
  165. loaded_units : tlinkedlist; { All loaded units }
  166. SmartLinkOFiles : TStringList; { List of .o files which are generated,
  167. used to delete them after linking }
  168. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  169. procedure addloadedunit(hp:tmodule);
  170. implementation
  171. uses
  172. {$IFDEF USE_SYSUTILS}
  173. SysUtils,
  174. GlobType,
  175. {$ELSE USE_SYSUTILS}
  176. dos,
  177. {$ENDIF USE_SYSUTILS}
  178. verbose,systems,
  179. scanner,ppu,
  180. procinfo;
  181. {*****************************************************************************
  182. Global Functions
  183. *****************************************************************************}
  184. function get_source_file(moduleindex,fileindex : longint) : tinputfile;
  185. var
  186. hp : tmodule;
  187. begin
  188. hp:=tmodule(loaded_units.first);
  189. while assigned(hp) and (hp.unit_index<>moduleindex) do
  190. hp:=tmodule(hp.next);
  191. if assigned(hp) then
  192. get_source_file:=hp.sourcefiles.get_file(fileindex)
  193. else
  194. get_source_file:=nil;
  195. end;
  196. procedure addloadedunit(hp:tmodule);
  197. begin
  198. hp.moduleid:=loaded_units.count;
  199. loaded_units.concat(hp);
  200. end;
  201. {****************************************************************************
  202. TLinkContainerItem
  203. ****************************************************************************}
  204. constructor TLinkContainerItem.Create(const s:string;m:cardinal);
  205. begin
  206. inherited Create;
  207. data:=stringdup(s);
  208. needlink:=m;
  209. end;
  210. destructor TLinkContainerItem.Destroy;
  211. begin
  212. stringdispose(data);
  213. end;
  214. {****************************************************************************
  215. TLinkContainer
  216. ****************************************************************************}
  217. procedure TLinkContainer.add(const s : string;m:cardinal);
  218. begin
  219. inherited concat(TLinkContainerItem.Create(s,m));
  220. end;
  221. function TLinkContainer.get(var m:cardinal) : string;
  222. var
  223. p : tlinkcontaineritem;
  224. begin
  225. p:=tlinkcontaineritem(inherited getfirst);
  226. if p=nil then
  227. begin
  228. get:='';
  229. m:=0;
  230. end
  231. else
  232. begin
  233. get:=p.data^;
  234. m:=p.needlink;
  235. p.free;
  236. end;
  237. end;
  238. function TLinkContainer.getusemask(mask:cardinal) : string;
  239. var
  240. p : tlinkcontaineritem;
  241. found : boolean;
  242. begin
  243. found:=false;
  244. repeat
  245. p:=tlinkcontaineritem(inherited getfirst);
  246. if p=nil then
  247. begin
  248. getusemask:='';
  249. exit;
  250. end;
  251. getusemask:=p.data^;
  252. found:=(p.needlink and mask)<>0;
  253. p.free;
  254. until found;
  255. end;
  256. function TLinkContainer.find(const s:string):boolean;
  257. var
  258. newnode : tlinkcontaineritem;
  259. begin
  260. find:=false;
  261. newnode:=tlinkcontaineritem(First);
  262. while assigned(newnode) do
  263. begin
  264. if newnode.data^=s then
  265. begin
  266. find:=true;
  267. exit;
  268. end;
  269. newnode:=tlinkcontaineritem(newnode.next);
  270. end;
  271. end;
  272. {****************************************************************************
  273. TExternalsItem
  274. ****************************************************************************}
  275. constructor tExternalsItem.Create(const s:string);
  276. begin
  277. inherited Create;
  278. found:=false;
  279. data:=stringdup(s);
  280. end;
  281. destructor tExternalsItem.Destroy;
  282. begin
  283. stringdispose(data);
  284. inherited;
  285. end;
  286. {****************************************************************************
  287. TUSED_UNIT
  288. ****************************************************************************}
  289. constructor tused_unit.create(_u : tmodule;intface,inuses:boolean;usym:tunitsym);
  290. begin
  291. u:=_u;
  292. in_interface:=intface;
  293. in_uses:=inuses;
  294. unitsym:=usym;
  295. if _u.state=ms_compiled then
  296. begin
  297. checksum:=u.crc;
  298. interface_checksum:=u.interface_crc;
  299. end
  300. else
  301. begin
  302. checksum:=0;
  303. interface_checksum:=0;
  304. end;
  305. end;
  306. {****************************************************************************
  307. TDENPENDENT_UNIT
  308. ****************************************************************************}
  309. constructor tdependent_unit.create(_u : tmodule);
  310. begin
  311. u:=_u;
  312. end;
  313. {****************************************************************************
  314. TMODULE
  315. ****************************************************************************}
  316. constructor tmodule.create(LoadedFrom:TModule;const s:string;_is_unit:boolean);
  317. var
  318. p : dirstr;
  319. n : namestr;
  320. e : extstr;
  321. begin
  322. {$IFDEF USE_SYSUTILS}
  323. p := SplitPath(s);
  324. n := SplitName(s);
  325. e := SplitExtension(s);
  326. {$ELSE USE_SYSUTILS}
  327. FSplit(s,p,n,e);
  328. {$ENDIF USE_SYSUTILS}
  329. { Programs have the name 'Program' to don't conflict with dup id's }
  330. if _is_unit then
  331. inherited create(n)
  332. else
  333. inherited create('Program');
  334. mainsource:=stringdup(s);
  335. { Dos has the famous 8.3 limit :( }
  336. {$ifdef shortasmprefix}
  337. asmprefix:=stringdup(FixFileName('as'));
  338. {$else}
  339. asmprefix:=stringdup(FixFileName(n));
  340. {$endif}
  341. setfilename(p+n,true);
  342. localunitsearchpath:=TSearchPathList.Create;
  343. localobjectsearchpath:=TSearchPathList.Create;
  344. localincludesearchpath:=TSearchPathList.Create;
  345. locallibrarysearchpath:=TSearchPathList.Create;
  346. used_units:=TLinkedList.Create;
  347. dependent_units:=TLinkedList.Create;
  348. resourcefiles:=TStringList.Create;
  349. linkunitofiles:=TLinkContainer.Create;
  350. linkunitstaticlibs:=TLinkContainer.Create;
  351. linkunitsharedlibs:=TLinkContainer.Create;
  352. linkotherofiles:=TLinkContainer.Create;
  353. linkotherstaticlibs:=TLinkContainer.Create;
  354. linkothersharedlibs:=TLinkContainer.Create;
  355. crc:=0;
  356. interface_crc:=0;
  357. flags:=0;
  358. scanner:=nil;
  359. unitmap:=nil;
  360. unitmapsize:=0;
  361. derefmap:=nil;
  362. derefmapsize:=0;
  363. derefmapcnt:=0;
  364. derefdata:=TDynamicArray.Create(1024);
  365. derefdataintflen:=0;
  366. globalsymtable:=nil;
  367. localsymtable:=nil;
  368. globalmacrosymtable:=nil;
  369. localmacrosymtable:=nil;
  370. loaded_from:=LoadedFrom;
  371. do_reload:=false;
  372. do_compile:=false;
  373. sources_avail:=true;
  374. mainfilepos.line:=0;
  375. mainfilepos.column:=0;
  376. mainfilepos.fileindex:=0;
  377. recompile_reason:=rr_unknown;
  378. in_interface:=true;
  379. in_global:=true;
  380. is_unit:=_is_unit;
  381. islibrary:=false;
  382. is_stab_written:=false;
  383. is_reset:=false;
  384. mode_switch_allowed:= true;
  385. uses_imports:=false;
  386. imports:=TLinkedList.Create;
  387. _exports:=TLinkedList.Create;
  388. externals:=TLinkedList.Create;
  389. librarydata:=tasmlibrarydata.create(realmodulename^);
  390. end;
  391. destructor tmodule.Destroy;
  392. var
  393. {$ifdef MEMDEBUG}
  394. d : tmemdebug;
  395. {$endif}
  396. i : longint;
  397. hpi : tprocinfo;
  398. begin
  399. if assigned(unitmap) then
  400. freemem(unitmap);
  401. if assigned(derefmap) then
  402. begin
  403. for i:=0 to derefmapcnt-1 do
  404. stringdispose(derefmap[i].modulename);
  405. freemem(derefmap);
  406. end;
  407. if assigned(imports) then
  408. imports.free;
  409. if assigned(_exports) then
  410. _exports.free;
  411. if assigned(externals) then
  412. externals.free;
  413. if assigned(scanner) then
  414. begin
  415. { also update current_scanner if it was pointing
  416. to this module }
  417. if current_scanner=tscannerfile(scanner) then
  418. current_scanner:=nil;
  419. tscannerfile(scanner).free;
  420. end;
  421. if assigned(procinfo) then
  422. begin
  423. if current_procinfo=tprocinfo(procinfo) then
  424. current_procinfo:=nil;
  425. { release procinfo tree }
  426. while assigned(procinfo) do
  427. begin
  428. hpi:=tprocinfo(procinfo).parent;
  429. tprocinfo(procinfo).free;
  430. procinfo:=hpi;
  431. end;
  432. end;
  433. used_units.free;
  434. dependent_units.free;
  435. resourcefiles.Free;
  436. linkunitofiles.Free;
  437. linkunitstaticlibs.Free;
  438. linkunitsharedlibs.Free;
  439. linkotherofiles.Free;
  440. linkotherstaticlibs.Free;
  441. linkothersharedlibs.Free;
  442. stringdispose(objfilename);
  443. stringdispose(newfilename);
  444. stringdispose(ppufilename);
  445. stringdispose(staticlibfilename);
  446. stringdispose(sharedlibfilename);
  447. stringdispose(exefilename);
  448. stringdispose(outputpath);
  449. stringdispose(path);
  450. stringdispose(realmodulename);
  451. stringdispose(mainsource);
  452. stringdispose(asmprefix);
  453. localunitsearchpath.Free;
  454. localobjectsearchpath.free;
  455. localincludesearchpath.free;
  456. locallibrarysearchpath.free;
  457. {$ifdef MEMDEBUG}
  458. d:=tmemdebug.create(modulename^+' - symtable');
  459. {$endif}
  460. derefdata.free;
  461. if assigned(globalsymtable) then
  462. globalsymtable.free;
  463. if assigned(localsymtable) then
  464. localsymtable.free;
  465. if assigned(globalmacrosymtable) then
  466. globalmacrosymtable.free;
  467. if assigned(localmacrosymtable) then
  468. localmacrosymtable.free;
  469. {$ifdef MEMDEBUG}
  470. d.free;
  471. {$endif}
  472. {$ifdef MEMDEBUG}
  473. d:=tmemdebug.create(modulename^+' - librarydata');
  474. {$endif}
  475. librarydata.free;
  476. {$ifdef MEMDEBUG}
  477. d.free;
  478. {$endif}
  479. stringdispose(modulename);
  480. inherited Destroy;
  481. end;
  482. procedure tmodule.reset;
  483. var
  484. hpi : tprocinfo;
  485. i : longint;
  486. begin
  487. if assigned(scanner) then
  488. begin
  489. { also update current_scanner if it was pointing
  490. to this module }
  491. if current_scanner=tscannerfile(scanner) then
  492. current_scanner:=nil;
  493. tscannerfile(scanner).free;
  494. scanner:=nil;
  495. end;
  496. if assigned(procinfo) then
  497. begin
  498. if current_procinfo=tprocinfo(procinfo) then
  499. current_procinfo:=nil;
  500. { release procinfo tree }
  501. while assigned(procinfo) do
  502. begin
  503. hpi:=tprocinfo(procinfo).parent;
  504. tprocinfo(procinfo).free;
  505. procinfo:=hpi;
  506. end;
  507. end;
  508. if assigned(globalsymtable) then
  509. begin
  510. globalsymtable.free;
  511. globalsymtable:=nil;
  512. end;
  513. if assigned(localsymtable) then
  514. begin
  515. localsymtable.free;
  516. localsymtable:=nil;
  517. end;
  518. if assigned(globalmacrosymtable) then
  519. begin
  520. globalmacrosymtable.free;
  521. globalmacrosymtable:=nil;
  522. end;
  523. if assigned(localmacrosymtable) then
  524. begin
  525. localmacrosymtable.free;
  526. localmacrosymtable:=nil;
  527. end;
  528. derefdata.free;
  529. derefdata:=TDynamicArray.Create(1024);
  530. if assigned(unitmap) then
  531. begin
  532. freemem(unitmap);
  533. unitmap:=nil;
  534. end;
  535. if assigned(derefmap) then
  536. begin
  537. for i:=0 to derefmapcnt-1 do
  538. stringdispose(derefmap[i].modulename);
  539. freemem(derefmap);
  540. derefmap:=nil;
  541. end;
  542. unitmapsize:=0;
  543. derefmapsize:=0;
  544. derefmapcnt:=0;
  545. derefdataintflen:=0;
  546. sourcefiles.free;
  547. sourcefiles:=tinputfilemanager.create;
  548. librarydata.free;
  549. librarydata:=tasmlibrarydata.create(realmodulename^);
  550. imports.free;
  551. imports:=tlinkedlist.create;
  552. _exports.free;
  553. _exports:=tlinkedlist.create;
  554. externals.free;
  555. externals:=tlinkedlist.create;
  556. used_units.free;
  557. used_units:=TLinkedList.Create;
  558. dependent_units.free;
  559. dependent_units:=TLinkedList.Create;
  560. resourcefiles.Free;
  561. resourcefiles:=TStringList.Create;
  562. linkunitofiles.Free;
  563. linkunitofiles:=TLinkContainer.Create;
  564. linkunitstaticlibs.Free;
  565. linkunitstaticlibs:=TLinkContainer.Create;
  566. linkunitsharedlibs.Free;
  567. linkunitsharedlibs:=TLinkContainer.Create;
  568. linkotherofiles.Free;
  569. linkotherofiles:=TLinkContainer.Create;
  570. linkotherstaticlibs.Free;
  571. linkotherstaticlibs:=TLinkContainer.Create;
  572. linkothersharedlibs.Free;
  573. linkothersharedlibs:=TLinkContainer.Create;
  574. uses_imports:=false;
  575. do_compile:=false;
  576. do_reload:=false;
  577. interface_compiled:=false;
  578. in_interface:=true;
  579. in_global:=true;
  580. mode_switch_allowed:=true;
  581. is_stab_written:=false;
  582. is_reset:=false;
  583. crc:=0;
  584. interface_crc:=0;
  585. flags:=0;
  586. mainfilepos.line:=0;
  587. mainfilepos.column:=0;
  588. mainfilepos.fileindex:=0;
  589. recompile_reason:=rr_unknown;
  590. {
  591. The following fields should not
  592. be reset:
  593. mainsource
  594. state
  595. loaded_from
  596. sources_avail
  597. }
  598. end;
  599. procedure tmodule.adddependency(callermodule:tmodule);
  600. begin
  601. { This is not needed for programs }
  602. if not callermodule.is_unit then
  603. exit;
  604. Message2(unit_u_add_depend_to,callermodule.modulename^,modulename^);
  605. dependent_units.concat(tdependent_unit.create(callermodule));
  606. end;
  607. procedure tmodule.flagdependent(callermodule:tmodule);
  608. var
  609. pm : tdependent_unit;
  610. begin
  611. { flag all units that depend on this unit for reloading }
  612. pm:=tdependent_unit(current_module.dependent_units.first);
  613. while assigned(pm) do
  614. begin
  615. { We do not have to reload the unit that wants to load
  616. this unit, unless this unit is already compiled during
  617. the loading }
  618. if (pm.u=callermodule) and
  619. (pm.u.state<>ms_compiled) then
  620. Message1(unit_u_no_reload_is_caller,pm.u.modulename^)
  621. else
  622. if pm.u.state=ms_second_compile then
  623. Message1(unit_u_no_reload_in_second_compile,pm.u.modulename^)
  624. else
  625. begin
  626. pm.u.do_reload:=true;
  627. Message1(unit_u_flag_for_reload,pm.u.modulename^);
  628. end;
  629. pm:=tdependent_unit(pm.next);
  630. end;
  631. end;
  632. function tmodule.addusedunit(hp:tmodule;inuses:boolean;usym:tunitsym):tused_unit;
  633. var
  634. pu : tused_unit;
  635. begin
  636. pu:=tused_unit.create(hp,in_interface,inuses,usym);
  637. used_units.concat(pu);
  638. addusedunit:=pu;
  639. end;
  640. procedure tmodule.updatemaps;
  641. var
  642. oldmapsize : longint;
  643. hp : tmodule;
  644. i : longint;
  645. begin
  646. { Extend unitmap }
  647. oldmapsize:=unitmapsize;
  648. unitmapsize:=loaded_units.count;
  649. reallocmem(unitmap,unitmapsize*sizeof(tunitmaprec));
  650. fillchar(unitmap[oldmapsize],(unitmapsize-oldmapsize)*sizeof(tunitmaprec),0);
  651. { Extend Derefmap }
  652. oldmapsize:=derefmapsize;
  653. derefmapsize:=loaded_units.count;
  654. reallocmem(derefmap,derefmapsize*sizeof(tderefmaprec));
  655. fillchar(derefmap[oldmapsize],(derefmapsize-oldmapsize)*sizeof(tderefmaprec),0);
  656. { Add all units to unitmap }
  657. hp:=tmodule(loaded_units.first);
  658. i:=0;
  659. while assigned(hp) do
  660. begin
  661. if hp.moduleid>=unitmapsize then
  662. internalerror(200501151);
  663. { Verify old entries }
  664. if (i<oldmapsize) then
  665. begin
  666. if (hp.moduleid<>i) or
  667. (unitmap[hp.moduleid].u<>hp) then
  668. internalerror(200501156);
  669. end
  670. else
  671. begin
  672. unitmap[hp.moduleid].u:=hp;
  673. unitmap[hp.moduleid].derefidx:=-1;
  674. end;
  675. inc(i);
  676. hp:=tmodule(hp.next);
  677. end;
  678. end;
  679. function tmodule.derefidx_unit(id:longint):longint;
  680. begin
  681. if id>=unitmapsize then
  682. internalerror(2005011511);
  683. if unitmap[id].derefidx=-1 then
  684. begin
  685. unitmap[id].derefidx:=derefmapcnt;
  686. inc(derefmapcnt);
  687. derefmap[unitmap[id].derefidx].u:=unitmap[id].u;
  688. end;
  689. if unitmap[id].derefidx>=derefmapsize then
  690. internalerror(2005011514);
  691. result:=unitmap[id].derefidx;
  692. end;
  693. function tmodule.resolve_unit(id:longint):tmodule;
  694. var
  695. hp : tmodule;
  696. begin
  697. if id>=derefmapsize then
  698. internalerror(200306231);
  699. result:=derefmap[id].u;
  700. if not assigned(result) then
  701. begin
  702. if not assigned(derefmap[id].modulename) or
  703. (derefmap[id].modulename^='') then
  704. internalerror(200501159);
  705. hp:=tmodule(loaded_units.first);
  706. while assigned(hp) do
  707. begin
  708. if hp.modulename^=derefmap[id].modulename^ then
  709. break;
  710. hp:=tmodule(hp.next);
  711. end;
  712. if not assigned(hp) then
  713. internalerror(2005011510);
  714. derefmap[id].u:=hp;
  715. result:=hp;
  716. end;
  717. end;
  718. procedure tmodule.allunitsused;
  719. var
  720. pu : tused_unit;
  721. begin
  722. pu:=tused_unit(used_units.first);
  723. while assigned(pu) do
  724. begin
  725. if assigned(pu.u.globalsymtable) then
  726. begin
  727. if unitmap[pu.u.moduleid].u<>pu.u then
  728. internalerror(200501157);
  729. { Give a note when the unit is not referenced, skip
  730. this is for units with an initialization/finalization }
  731. if (unitmap[pu.u.moduleid].refs=0) and
  732. ((pu.u.flags and (uf_init or uf_finalize))=0) then
  733. CGMessagePos2(pu.unitsym.fileinfo,sym_n_unit_not_used,pu.u.realmodulename^,realmodulename^);
  734. end;
  735. pu:=tused_unit(pu.next);
  736. end;
  737. end;
  738. procedure tmodule.setmodulename(const s:string);
  739. begin
  740. stringdispose(modulename);
  741. stringdispose(realmodulename);
  742. modulename:=stringdup(upper(s));
  743. realmodulename:=stringdup(s);
  744. { also update asmlibrary names }
  745. librarydata.name:=modulename^;
  746. librarydata.realname:=realmodulename^;
  747. end;
  748. end.
  749. {
  750. $Log$
  751. Revision 1.53 2005-02-14 17:13:06 peter
  752. * truncate log
  753. Revision 1.52 2005/01/19 22:19:41 peter
  754. * unit mapping rewrite
  755. * new derefmap added
  756. Revision 1.51 2005/01/09 20:24:43 olle
  757. * rework of macro subsystem
  758. + exportable macros for mode macpas
  759. }