fppu.pas 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  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 fppu;
  19. {$i fpcdefs.inc}
  20. { close ppufiles on system that are
  21. short on file handles like DOS system PM }
  22. {$ifdef GO32V2}
  23. {$define SHORT_ON_FILE_HANDLES}
  24. {$endif GO32V2}
  25. interface
  26. uses
  27. cutils,cclasses,
  28. globtype,globals,finput,fmodule,
  29. symbase,symppu,ppu;
  30. type
  31. tppumodule = class(tmodule)
  32. ppufile : tcompilerppufile; { the PPU file }
  33. {$ifdef Test_Double_checksum}
  34. crc_array : pointer;
  35. crc_size : longint;
  36. crc_array2 : pointer;
  37. crc_size2 : longint;
  38. {$endif def Test_Double_checksum}
  39. constructor create(LoadedFrom:TModule;const s:string;const fn:string;_is_unit:boolean);
  40. destructor destroy;override;
  41. procedure reset;override;
  42. function openppu:boolean;
  43. function search_unit(const n : string;const fn:string;onlysource:boolean):boolean;
  44. procedure getppucrc;
  45. procedure writeppu;
  46. procedure loadppu;
  47. private
  48. procedure load_interface;
  49. procedure load_implementation;
  50. procedure load_symtable_refs;
  51. procedure load_usedunits;
  52. procedure writeusedmacro(p:TNamedIndexItem;arg:pointer);
  53. procedure writeusedmacros;
  54. procedure writesourcefiles;
  55. procedure writeusedunit;
  56. procedure writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  57. procedure putasmsymbol_in_idx(s:tnamedindexitem;arg:pointer);
  58. procedure writeasmsymbols;
  59. procedure readusedmacros;
  60. procedure readsourcefiles;
  61. procedure readloadunit;
  62. procedure readlinkcontainer(var p:tlinkcontainer);
  63. procedure readasmsymbols;
  64. end;
  65. function loadunit(const s : stringid;const fn:string) : tmodule;
  66. implementation
  67. uses
  68. verbose,systems,version,
  69. symtable,
  70. scanner,
  71. aasmbase,
  72. parser;
  73. {****************************************************************************
  74. TPPUMODULE
  75. ****************************************************************************}
  76. constructor tppumodule.create(LoadedFrom:TModule;const s:string;const fn:string;_is_unit:boolean);
  77. begin
  78. inherited create(LoadedFrom,s,_is_unit);
  79. ppufile:=nil;
  80. { search the PPU file if it is an unit }
  81. if is_unit then
  82. begin
  83. { use the realmodulename so we can also find a case sensitive
  84. source filename }
  85. search_unit(realmodulename^,fn,false);
  86. { it the sources_available is changed then we know that
  87. the sources aren't available }
  88. if not sources_avail then
  89. sources_checked:=true;
  90. end;
  91. end;
  92. destructor tppumodule.Destroy;
  93. begin
  94. if assigned(ppufile) then
  95. ppufile.free;
  96. ppufile:=nil;
  97. inherited Destroy;
  98. end;
  99. procedure tppumodule.reset;
  100. begin
  101. if assigned(ppufile) then
  102. begin
  103. ppufile.free;
  104. ppufile:=nil;
  105. end;
  106. inherited reset;
  107. end;
  108. function tppumodule.openppu:boolean;
  109. var
  110. ppufiletime : longint;
  111. begin
  112. openppu:=false;
  113. Message1(unit_t_ppu_loading,ppufilename^);
  114. { Get ppufile time (also check if the file exists) }
  115. ppufiletime:=getnamedfiletime(ppufilename^);
  116. if ppufiletime=-1 then
  117. exit;
  118. { Open the ppufile }
  119. Message1(unit_u_ppu_name,ppufilename^);
  120. ppufile:=tcompilerppufile.create(ppufilename^);
  121. if not ppufile.openfile then
  122. begin
  123. ppufile.free;
  124. ppufile:=nil;
  125. Message(unit_u_ppu_file_too_short);
  126. exit;
  127. end;
  128. { check for a valid PPU file }
  129. if not ppufile.CheckPPUId then
  130. begin
  131. ppufile.free;
  132. ppufile:=nil;
  133. Message(unit_u_ppu_invalid_header);
  134. exit;
  135. end;
  136. { check for allowed PPU versions }
  137. if not (ppufile.GetPPUVersion = CurrentPPUVersion) then
  138. begin
  139. Message1(unit_u_ppu_invalid_version,tostr(ppufile.GetPPUVersion));
  140. ppufile.free;
  141. ppufile:=nil;
  142. exit;
  143. end;
  144. { check the target processor }
  145. if tsystemcpu(ppufile.header.cpu)<>target_cpu then
  146. begin
  147. ppufile.free;
  148. ppufile:=nil;
  149. Message(unit_u_ppu_invalid_processor);
  150. exit;
  151. end;
  152. { check target }
  153. if tsystem(ppufile.header.target)<>target_info.system then
  154. begin
  155. ppufile.free;
  156. ppufile:=nil;
  157. Message(unit_u_ppu_invalid_target);
  158. exit;
  159. end;
  160. { check if floating point emulation is on?}
  161. if ((ppufile.header.flags and uf_fpu_emulation)<>0) and
  162. (cs_fp_emulation in aktmoduleswitches) then
  163. begin
  164. ppufile.free;
  165. ppufile:=nil;
  166. Message(unit_u_ppu_invalid_fpumode);
  167. exit;
  168. end;
  169. { Load values to be access easier }
  170. flags:=ppufile.header.flags;
  171. crc:=ppufile.header.checksum;
  172. interface_crc:=ppufile.header.interface_checksum;
  173. { Show Debug info }
  174. Message1(unit_u_ppu_time,filetimestring(ppufiletime));
  175. Message1(unit_u_ppu_flags,tostr(flags));
  176. Message1(unit_u_ppu_crc,hexstr(ppufile.header.checksum,8));
  177. Message1(unit_u_ppu_crc,hexstr(ppufile.header.interface_checksum,8)+' (intfc)');
  178. do_compile:=false;
  179. openppu:=true;
  180. end;
  181. function tppumodule.search_unit(const n : string;const fn:string;onlysource:boolean):boolean;
  182. var
  183. singlepathstring,
  184. filename : string;
  185. Function UnitExists(const ext:string;var foundfile:string):boolean;
  186. begin
  187. Message1(unit_t_unitsearch,Singlepathstring+filename+ext);
  188. UnitExists:=FindFile(FileName+ext,Singlepathstring,foundfile);
  189. end;
  190. Function PPUSearchPath(const s:string):boolean;
  191. var
  192. found : boolean;
  193. hs : string;
  194. begin
  195. Found:=false;
  196. singlepathstring:=FixPath(s,false);
  197. { Check for PPU file }
  198. Found:=UnitExists(target_info.unitext,hs);
  199. if Found then
  200. Begin
  201. SetFileName(hs,false);
  202. Found:=OpenPPU;
  203. End;
  204. PPUSearchPath:=Found;
  205. end;
  206. Function SourceSearchPath(const s:string):boolean;
  207. var
  208. found : boolean;
  209. hs : string;
  210. begin
  211. Found:=false;
  212. singlepathstring:=FixPath(s,false);
  213. { Check for Sources }
  214. ppufile:=nil;
  215. do_compile:=true;
  216. recompile_reason:=rr_noppu;
  217. {Check for .pp file}
  218. Found:=UnitExists(target_info.sourceext,hs);
  219. if not Found then
  220. begin
  221. { Check for .pas }
  222. Found:=UnitExists(target_info.pasext,hs);
  223. end;
  224. stringdispose(mainsource);
  225. if Found then
  226. begin
  227. sources_avail:=true;
  228. { Load Filenames when found }
  229. mainsource:=StringDup(hs);
  230. SetFileName(hs,false);
  231. end
  232. else
  233. sources_avail:=false;
  234. SourceSearchPath:=Found;
  235. end;
  236. Function SearchPath(const s:string):boolean;
  237. var
  238. found : boolean;
  239. begin
  240. { First check for a ppu, then for the source }
  241. found:=false;
  242. if not onlysource then
  243. found:=PPUSearchPath(s);
  244. if not found then
  245. found:=SourceSearchPath(s);
  246. SearchPath:=found;
  247. end;
  248. Function SearchPathList(list:TSearchPathList):boolean;
  249. var
  250. hp : TStringListItem;
  251. found : boolean;
  252. begin
  253. found:=false;
  254. hp:=TStringListItem(list.First);
  255. while assigned(hp) do
  256. begin
  257. found:=SearchPath(hp.Str);
  258. if found then
  259. break;
  260. hp:=TStringListItem(hp.next);
  261. end;
  262. SearchPathList:=found;
  263. end;
  264. var
  265. fnd : boolean;
  266. hs : string;
  267. begin
  268. filename:=FixFileName(n);
  269. { try to find unit
  270. 1. look for ppu in cwd
  271. 2. look for ppu in outputpath if set, this is tp7 compatible (PFV)
  272. 3. look for the specified source file (from the uses line)
  273. 4. look for source in cwd
  274. 5. local unit pathlist
  275. 6. global unit pathlist }
  276. fnd:=false;
  277. if not onlysource then
  278. begin
  279. fnd:=PPUSearchPath('.');
  280. if (not fnd) and (outputpath^<>'') then
  281. fnd:=PPUSearchPath(outputpath^);
  282. end;
  283. if (not fnd) and (fn<>'') then
  284. begin
  285. { the full filename is specified so we can't use here the
  286. searchpath (PFV) }
  287. Message1(unit_t_unitsearch,AddExtension(fn,target_info.sourceext));
  288. fnd:=FindFile(AddExtension(fn,target_info.sourceext),'',hs);
  289. if not fnd then
  290. begin
  291. Message1(unit_t_unitsearch,AddExtension(fn,target_info.pasext));
  292. fnd:=FindFile(AddExtension(fn,target_info.pasext),'',hs);
  293. end;
  294. if fnd then
  295. begin
  296. sources_avail:=true;
  297. do_compile:=true;
  298. recompile_reason:=rr_noppu;
  299. stringdispose(mainsource);
  300. mainsource:=StringDup(hs);
  301. SetFileName(hs,false);
  302. end;
  303. end;
  304. if(not fnd)and Assigned(Loaded_From)
  305. then
  306. fnd:=SearchPathList(Loaded_From.LocalUnitSearchPath);
  307. if not fnd
  308. then
  309. fnd:=SourceSearchPath('.');
  310. if not fnd
  311. then
  312. fnd:=SearchPathList(LocalUnitSearchPath);
  313. if not fnd
  314. then
  315. fnd:=SearchPathList(UnitSearchPath);
  316. { try to find a file with the first 8 chars of the modulename, like
  317. dos }
  318. if (not fnd) and (length(filename)>8) then
  319. begin
  320. filename:=copy(filename,1,8);
  321. fnd:=SearchPath('.');
  322. if (not fnd) then
  323. fnd:=SearchPathList(LocalUnitSearchPath);
  324. if not fnd then
  325. fnd:=SearchPathList(UnitSearchPath);
  326. end;
  327. search_unit:=fnd;
  328. end;
  329. {**********************************
  330. PPU Reading/Writing Helpers
  331. ***********************************}
  332. procedure tppumodule.writeusedmacro(p:TNamedIndexItem;arg:pointer);
  333. begin
  334. if tmacro(p).is_used or tmacro(p).defined_at_startup then
  335. begin
  336. ppufile.putstring(p.name);
  337. ppufile.putbyte(byte(tmacro(p).defined_at_startup));
  338. ppufile.putbyte(byte(tmacro(p).is_used));
  339. end;
  340. end;
  341. procedure tppumodule.writeusedmacros;
  342. begin
  343. ppufile.do_crc:=false;
  344. tscannerfile(scanner).macros.foreach({$ifdef FPCPROCVAR}@{$endif}writeusedmacro,nil);
  345. ppufile.writeentry(ibusedmacros);
  346. ppufile.do_crc:=true;
  347. end;
  348. procedure tppumodule.writesourcefiles;
  349. var
  350. hp : tinputfile;
  351. i,j : longint;
  352. begin
  353. { second write the used source files }
  354. ppufile.do_crc:=false;
  355. hp:=sourcefiles.files;
  356. { write source files directly in good order }
  357. j:=0;
  358. while assigned(hp) do
  359. begin
  360. inc(j);
  361. hp:=hp.ref_next;
  362. end;
  363. while j>0 do
  364. begin
  365. hp:=sourcefiles.files;
  366. for i:=1 to j-1 do
  367. hp:=hp.ref_next;
  368. ppufile.putstring(hp.name^);
  369. ppufile.putlongint(hp.getfiletime);
  370. dec(j);
  371. end;
  372. ppufile.writeentry(ibsourcefiles);
  373. ppufile.do_crc:=true;
  374. end;
  375. procedure tppumodule.writeusedunit;
  376. var
  377. hp : tused_unit;
  378. begin
  379. { renumber the units for derefence writing }
  380. numberunits;
  381. { write a reference for each used unit }
  382. hp:=tused_unit(used_units.first);
  383. while assigned(hp) do
  384. begin
  385. { implementation units should not change
  386. the CRC PM }
  387. ppufile.do_crc:=hp.in_interface;
  388. ppufile.putstring(hp.realname^);
  389. { the checksum should not affect the crc of this unit ! (PFV) }
  390. ppufile.do_crc:=false;
  391. ppufile.putlongint(longint(hp.checksum));
  392. ppufile.putlongint(longint(hp.interface_checksum));
  393. ppufile.putbyte(byte(hp.in_interface));
  394. ppufile.do_crc:=true;
  395. hp:=tused_unit(hp.next);
  396. end;
  397. ppufile.do_interface_crc:=true;
  398. ppufile.writeentry(ibloadunit);
  399. end;
  400. procedure tppumodule.writelinkcontainer(var p:tlinkcontainer;id:byte;strippath:boolean);
  401. var
  402. hcontainer : tlinkcontainer;
  403. s : string;
  404. mask : cardinal;
  405. begin
  406. hcontainer:=TLinkContainer.Create;
  407. while not p.empty do
  408. begin
  409. s:=p.get(mask);
  410. if strippath then
  411. ppufile.putstring(SplitFileName(s))
  412. else
  413. ppufile.putstring(s);
  414. ppufile.putlongint(mask);
  415. hcontainer.add(s,mask);
  416. end;
  417. ppufile.writeentry(id);
  418. p.Free;
  419. p:=hcontainer;
  420. end;
  421. procedure tppumodule.putasmsymbol_in_idx(s:tnamedindexitem;arg:pointer);
  422. begin
  423. if tasmsymbol(s).ppuidx<>-1 then
  424. librarydata.asmsymbolidx^[tasmsymbol(s).ppuidx-1]:=tasmsymbol(s);
  425. end;
  426. procedure tppumodule.writeasmsymbols;
  427. var
  428. s : tasmsymbol;
  429. i : longint;
  430. asmsymtype : byte;
  431. begin
  432. { get an ordered list of all symbols to put in the ppu }
  433. getmem(librarydata.asmsymbolidx,librarydata.asmsymbolppuidx*sizeof(pointer));
  434. fillchar(librarydata.asmsymbolidx^,librarydata.asmsymbolppuidx*sizeof(pointer),0);
  435. librarydata.symbolsearch.foreach({$ifdef FPCPROCVAR}@{$endif}putasmsymbol_in_idx,nil);
  436. { write the number of symbols }
  437. ppufile.putlongint(librarydata.asmsymbolppuidx);
  438. { write the symbols from the indexed list to the ppu }
  439. for i:=1 to librarydata.asmsymbolppuidx do
  440. begin
  441. s:=librarydata.asmsymbolidx^[i-1];
  442. if not assigned(s) then
  443. internalerror(200208071);
  444. asmsymtype:=1;
  445. if s.Classtype=tasmlabel then
  446. begin
  447. if tasmlabel(s).is_addr then
  448. asmsymtype:=4
  449. else if tasmlabel(s).typ=AT_DATA then
  450. asmsymtype:=3
  451. else
  452. asmsymtype:=2;
  453. end;
  454. ppufile.putbyte(asmsymtype);
  455. case asmsymtype of
  456. 1 :
  457. ppufile.putstring(s.name);
  458. 2 :
  459. ppufile.putlongint(tasmlabel(s).labelnr);
  460. end;
  461. ppufile.putbyte(byte(s.defbind));
  462. ppufile.putbyte(byte(s.typ));
  463. end;
  464. ppufile.writeentry(ibasmsymbols);
  465. end;
  466. procedure tppumodule.readusedmacros;
  467. var
  468. hs : string;
  469. mac : tmacro;
  470. was_defined_at_startup,
  471. was_used : boolean;
  472. begin
  473. { only possible when we've a scanner of the current file }
  474. if not assigned(current_scanner) then
  475. exit;
  476. while not ppufile.endofentry do
  477. begin
  478. hs:=ppufile.getstring;
  479. was_defined_at_startup:=boolean(ppufile.getbyte);
  480. was_used:=boolean(ppufile.getbyte);
  481. mac:=tmacro(tscannerfile(current_scanner).macros.search(hs));
  482. if assigned(mac) then
  483. begin
  484. {$ifndef EXTDEBUG}
  485. { if we don't have the sources why tell }
  486. if sources_avail then
  487. {$endif ndef EXTDEBUG}
  488. if (not was_defined_at_startup) and
  489. was_used and
  490. mac.defined_at_startup then
  491. Message2(unit_h_cond_not_set_in_last_compile,hs,mainsource^);
  492. end
  493. else { not assigned }
  494. if was_defined_at_startup and
  495. was_used then
  496. Message2(unit_h_cond_set_in_last_compile,hs,mainsource^);
  497. end;
  498. end;
  499. procedure tppumodule.readsourcefiles;
  500. var
  501. temp,hs : string;
  502. temp_dir : string;
  503. main_dir : string;
  504. incfile_found,
  505. main_found,
  506. is_main : boolean;
  507. orgfiletime,
  508. source_time : longint;
  509. hp : tinputfile;
  510. begin
  511. sources_avail:=true;
  512. is_main:=true;
  513. main_dir:='';
  514. while not ppufile.endofentry do
  515. begin
  516. hs:=ppufile.getstring;
  517. orgfiletime:=ppufile.getlongint;
  518. temp_dir:='';
  519. if (flags and uf_in_library)<>0 then
  520. begin
  521. sources_avail:=false;
  522. temp:=' library';
  523. end
  524. else if pos('Macro ',hs)=1 then
  525. begin
  526. { we don't want to find this file }
  527. { but there is a problem with file indexing !! }
  528. temp:='';
  529. end
  530. else
  531. begin
  532. { check the date of the source files }
  533. Source_Time:=GetNamedFileTime(path^+hs);
  534. incfile_found:=false;
  535. main_found:=false;
  536. if Source_Time<>-1 then
  537. hs:=path^+hs
  538. else
  539. if not(is_main) then
  540. begin
  541. Source_Time:=GetNamedFileTime(main_dir+hs);
  542. if Source_Time<>-1 then
  543. hs:=main_dir+hs;
  544. end;
  545. if (Source_Time=-1) then
  546. begin
  547. if is_main then
  548. main_found:=unitsearchpath.FindFile(hs,temp_dir)
  549. else
  550. incfile_found:=includesearchpath.FindFile(hs,temp_dir);
  551. if incfile_found or main_found then
  552. begin
  553. Source_Time:=GetNamedFileTime(temp_dir);
  554. if Source_Time<>-1 then
  555. hs:=temp_dir;
  556. end;
  557. end;
  558. if Source_Time=-1 then
  559. begin
  560. sources_avail:=false;
  561. temp:=' not found';
  562. end
  563. else
  564. begin
  565. if main_found then
  566. main_dir:=temp_dir;
  567. { time newer? But only allow if the file is not searched
  568. in the include path (PFV), else you've problems with
  569. units which use the same includefile names }
  570. if incfile_found then
  571. temp:=' found'
  572. else
  573. begin
  574. temp:=' time '+filetimestring(source_time);
  575. if (orgfiletime<>-1) and
  576. (source_time<>orgfiletime) then
  577. begin
  578. if ((flags and uf_release)=0) then
  579. begin
  580. do_compile:=true;
  581. recompile_reason:=rr_sourcenewer;
  582. end
  583. else
  584. Message2(unit_h_source_modified,hs,ppufilename^);
  585. temp:=temp+' *';
  586. end;
  587. end;
  588. end;
  589. hp:=tinputfile.create(hs);
  590. { the indexing is wrong here PM }
  591. sourcefiles.register_file(hp);
  592. end;
  593. if is_main then
  594. begin
  595. stringdispose(mainsource);
  596. mainsource:=stringdup(hs);
  597. end;
  598. Message1(unit_u_ppu_source,hs+temp);
  599. is_main:=false;
  600. end;
  601. { check if we want to rebuild every unit, only if the sources are
  602. available }
  603. if do_build and sources_avail and
  604. ((flags and uf_release)=0) then
  605. begin
  606. do_compile:=true;
  607. recompile_reason:=rr_build;
  608. end;
  609. end;
  610. procedure tppumodule.readloadunit;
  611. var
  612. hs : string;
  613. intfchecksum,
  614. checksum : cardinal;
  615. in_interface : boolean;
  616. begin
  617. while not ppufile.endofentry do
  618. begin
  619. hs:=ppufile.getstring;
  620. checksum:=cardinal(ppufile.getlongint);
  621. intfchecksum:=cardinal(ppufile.getlongint);
  622. in_interface:=(ppufile.getbyte<>0);
  623. used_units.concat(tused_unit.create_to_load(hs,checksum,intfchecksum,in_interface));
  624. end;
  625. end;
  626. procedure tppumodule.readlinkcontainer(var p:tlinkcontainer);
  627. var
  628. s : string;
  629. m : longint;
  630. begin
  631. while not ppufile.endofentry do
  632. begin
  633. s:=ppufile.getstring;
  634. m:=ppufile.getlongint;
  635. p.add(s,m);
  636. end;
  637. end;
  638. procedure tppumodule.readasmsymbols;
  639. var
  640. labelnr,
  641. i : longint;
  642. name : string;
  643. bind : TAsmSymBind;
  644. typ : TAsmSymType;
  645. asmsymtype : byte;
  646. begin
  647. librarydata.asmsymbolppuidx:=ppufile.getlongint;
  648. if librarydata.asmsymbolppuidx>0 then
  649. begin
  650. getmem(librarydata.asmsymbolidx,librarydata.asmsymbolppuidx*sizeof(pointer));
  651. fillchar(librarydata.asmsymbolidx^,librarydata.asmsymbolppuidx*sizeof(pointer),0);
  652. for i:=1 to librarydata.asmsymbolppuidx do
  653. begin
  654. asmsymtype:=ppufile.getbyte;
  655. case asmsymtype of
  656. 1 :
  657. name:=ppufile.getstring;
  658. 2..4 :
  659. labelnr:=ppufile.getlongint;
  660. else
  661. internalerror(200208192);
  662. end;
  663. bind:=tasmsymbind(ppufile.getbyte);
  664. typ:=tasmsymtype(ppufile.getbyte);
  665. case asmsymtype of
  666. 1 :
  667. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmsymboltype(name,bind,typ);
  668. 2 :
  669. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,false,false);
  670. 3 :
  671. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,true,false);
  672. 4 :
  673. librarydata.asmsymbolidx^[i-1]:=librarydata.newasmlabel(labelnr,false,true);
  674. end;
  675. end;
  676. end;
  677. end;
  678. procedure tppumodule.load_interface;
  679. var
  680. b : byte;
  681. newmodulename : string;
  682. begin
  683. { read interface part }
  684. repeat
  685. b:=ppufile.readentry;
  686. case b of
  687. ibmodulename :
  688. begin
  689. newmodulename:=ppufile.getstring;
  690. if (cs_check_unit_name in aktglobalswitches) and
  691. (upper(newmodulename)<>modulename^) then
  692. Message2(unit_f_unit_name_error,realmodulename^,newmodulename);
  693. stringdispose(modulename);
  694. stringdispose(realmodulename);
  695. modulename:=stringdup(upper(newmodulename));
  696. realmodulename:=stringdup(newmodulename);
  697. end;
  698. ibsourcefiles :
  699. readsourcefiles;
  700. ibusedmacros :
  701. readusedmacros;
  702. ibloadunit :
  703. readloadunit;
  704. iblinkunitofiles :
  705. readlinkcontainer(LinkUnitOFiles);
  706. iblinkunitstaticlibs :
  707. readlinkcontainer(LinkUnitStaticLibs);
  708. iblinkunitsharedlibs :
  709. readlinkcontainer(LinkUnitSharedLibs);
  710. iblinkotherofiles :
  711. readlinkcontainer(LinkotherOFiles);
  712. iblinkotherstaticlibs :
  713. readlinkcontainer(LinkotherStaticLibs);
  714. iblinkothersharedlibs :
  715. readlinkcontainer(LinkotherSharedLibs);
  716. ibendinterface :
  717. break;
  718. else
  719. Message1(unit_f_ppu_invalid_entry,tostr(b));
  720. end;
  721. until false;
  722. end;
  723. procedure tppumodule.load_implementation;
  724. var
  725. b : byte;
  726. oldobjectlibrary : tasmlibrarydata;
  727. begin
  728. { read implementation part }
  729. repeat
  730. b:=ppufile.readentry;
  731. case b of
  732. ibasmsymbols :
  733. readasmsymbols;
  734. ibendimplementation :
  735. break;
  736. else
  737. Message1(unit_f_ppu_invalid_entry,tostr(b));
  738. end;
  739. until false;
  740. { we can now derefence all pointers to the implementation parts }
  741. oldobjectlibrary:=objectlibrary;
  742. objectlibrary:=librarydata;
  743. tstoredsymtable(globalsymtable).derefimpl;
  744. if assigned(localsymtable) then
  745. tstoredsymtable(localsymtable).derefimpl;
  746. objectlibrary:=oldobjectlibrary;
  747. end;
  748. procedure tppumodule.load_symtable_refs;
  749. var
  750. b : byte;
  751. unitindex : word;
  752. begin
  753. { load local symtable first }
  754. if ((flags and uf_local_browser)<>0) then
  755. begin
  756. localsymtable:=tstaticsymtable.create(modulename^);
  757. tstaticsymtable(localsymtable).ppuload(ppufile);
  758. end;
  759. { load browser }
  760. if (flags and uf_has_browser)<>0 then
  761. begin
  762. tstoredsymtable(globalsymtable).load_references(ppufile,true);
  763. unitindex:=1;
  764. while assigned(map^[unitindex]) do
  765. begin
  766. { each unit wrote one browser entry }
  767. tstoredsymtable(globalsymtable).load_references(ppufile,false);
  768. inc(unitindex);
  769. end;
  770. b:=ppufile.readentry;
  771. if b<>ibendbrowser then
  772. Message1(unit_f_ppu_invalid_entry,tostr(b));
  773. end;
  774. if ((flags and uf_local_browser)<>0) then
  775. tstaticsymtable(localsymtable).load_references(ppufile,true);
  776. end;
  777. procedure tppumodule.writeppu;
  778. var
  779. pu : tused_unit;
  780. begin
  781. Message1(unit_u_ppu_write,realmodulename^);
  782. { create unit flags }
  783. {$ifdef GDB}
  784. if cs_gdb_dbx in aktglobalswitches then
  785. flags:=flags or uf_has_dbx;
  786. {$endif GDB}
  787. if cs_browser in aktmoduleswitches then
  788. flags:=flags or uf_has_browser;
  789. if cs_local_browser in aktmoduleswitches then
  790. flags:=flags or uf_local_browser;
  791. if do_release then
  792. flags:=flags or uf_release;
  793. if (cs_fp_emulation in aktmoduleswitches) then
  794. flags:=flags or uf_fpu_emulation;
  795. {$ifdef Test_Double_checksum_write}
  796. Assign(CRCFile,s+'.IMP');
  797. Rewrite(CRCFile);
  798. {$endif def Test_Double_checksum_write}
  799. { create new ppufile }
  800. ppufile:=tcompilerppufile.create(ppufilename^);
  801. if not ppufile.createfile then
  802. Message(unit_f_ppu_cannot_write);
  803. { first the unitname }
  804. ppufile.putstring(realmodulename^);
  805. ppufile.writeentry(ibmodulename);
  806. writesourcefiles;
  807. writeusedmacros;
  808. writeusedunit;
  809. { write the objectfiles and libraries that come for this unit,
  810. preserve the containers becuase they are still needed to load
  811. the link.res. All doesn't depend on the crc! It doesn't matter
  812. if a unit is in a .o or .a file }
  813. ppufile.do_crc:=false;
  814. writelinkcontainer(linkunitofiles,iblinkunitofiles,true);
  815. writelinkcontainer(linkunitstaticlibs,iblinkunitstaticlibs,true);
  816. writelinkcontainer(linkunitsharedlibs,iblinkunitsharedlibs,true);
  817. writelinkcontainer(linkotherofiles,iblinkotherofiles,false);
  818. writelinkcontainer(linkotherstaticlibs,iblinkotherstaticlibs,true);
  819. writelinkcontainer(linkothersharedlibs,iblinkothersharedlibs,true);
  820. ppufile.do_crc:=true;
  821. ppufile.writeentry(ibendinterface);
  822. { write the symtable entries }
  823. tstoredsymtable(globalsymtable).ppuwrite(ppufile);
  824. { everything after this doesn't affect the crc }
  825. ppufile.do_crc:=false;
  826. { write asmsymbols }
  827. writeasmsymbols;
  828. { end of implementation }
  829. ppufile.writeentry(ibendimplementation);
  830. { write static symtable
  831. needed for local debugging of unit functions }
  832. if ((flags and uf_local_browser)<>0) and
  833. assigned(localsymtable) then
  834. tstoredsymtable(localsymtable).ppuwrite(ppufile);
  835. { write all browser section }
  836. if (flags and uf_has_browser)<>0 then
  837. begin
  838. tstoredsymtable(globalsymtable).write_references(ppufile,true);
  839. pu:=tused_unit(used_units.first);
  840. while assigned(pu) do
  841. begin
  842. tstoredsymtable(pu.u.globalsymtable).write_references(ppufile,false);
  843. pu:=tused_unit(pu.next);
  844. end;
  845. ppufile.writeentry(ibendbrowser);
  846. end;
  847. if ((flags and uf_local_browser)<>0) and
  848. assigned(localsymtable) then
  849. tstaticsymtable(localsymtable).write_references(ppufile,true);
  850. { the last entry ibend is written automaticly }
  851. { flush to be sure }
  852. ppufile.flush;
  853. { create and write header }
  854. ppufile.header.size:=ppufile.size;
  855. ppufile.header.checksum:=ppufile.crc;
  856. ppufile.header.interface_checksum:=ppufile.interface_crc;
  857. ppufile.header.compiler:=wordversion;
  858. ppufile.header.cpu:=word(target_cpu);
  859. ppufile.header.target:=word(target_info.system);
  860. ppufile.header.flags:=flags;
  861. ppufile.writeheader;
  862. { save crc in current module also }
  863. crc:=ppufile.crc;
  864. interface_crc:=ppufile.interface_crc;
  865. {$ifdef Test_Double_checksum_write}
  866. close(CRCFile);
  867. {$endif Test_Double_checksum_write}
  868. ppufile.closefile;
  869. ppufile.free;
  870. ppufile:=nil;
  871. end;
  872. procedure tppumodule.getppucrc;
  873. begin
  874. {$ifdef Test_Double_checksum_write}
  875. Assign(CRCFile,s+'.INT')
  876. Rewrite(CRCFile);
  877. {$endif def Test_Double_checksum_write}
  878. { create new ppufile }
  879. ppufile:=tcompilerppufile.create(ppufilename^);
  880. ppufile.crc_only:=true;
  881. if not ppufile.createfile then
  882. Message(unit_f_ppu_cannot_write);
  883. { first the unitname }
  884. ppufile.putstring(realmodulename^);
  885. ppufile.writeentry(ibmodulename);
  886. { the interface units affect the crc }
  887. writeusedunit;
  888. ppufile.writeentry(ibendinterface);
  889. { write the symtable entries }
  890. tstoredsymtable(globalsymtable).ppuwrite(ppufile);
  891. { save crc }
  892. crc:=ppufile.crc;
  893. interface_crc:=ppufile.interface_crc;
  894. {$ifdef Test_Double_checksum}
  895. crc_array:=ppufile.crc_test;
  896. ppufile.crc_test:=nil;
  897. crc_size:=ppufile.crc_index2;
  898. crc_array2:=ppufile.crc_test2;
  899. ppufile.crc_test2:=nil;
  900. crc_size2:=ppufile.crc_index2;
  901. {$endif Test_Double_checksum}
  902. {$ifdef Test_Double_checksum_write}
  903. close(CRCFile);
  904. {$endif Test_Double_checksum_write}
  905. ppufile.closefile;
  906. ppufile.free;
  907. ppufile:=nil;
  908. end;
  909. procedure tppumodule.load_usedunits;
  910. var
  911. pu : tused_unit;
  912. loaded_unit : tmodule;
  913. load_refs : boolean;
  914. nextmapentry : longint;
  915. begin
  916. load_refs:=true;
  917. { init the map }
  918. new(map);
  919. fillchar(map^,sizeof(tunitmap),#0);
  920. {$ifdef NEWMAP}
  921. map^[0]:=current_module;
  922. {$endif NEWMAP}
  923. nextmapentry:=1;
  924. { load the used units from interface }
  925. in_implementation:=false;
  926. pu:=tused_unit(used_units.first);
  927. while assigned(pu) do
  928. begin
  929. if (not pu.loaded) and (pu.in_interface) then
  930. begin
  931. loaded_unit:=loadunit(pu.realname^,'');
  932. if compiled then
  933. exit;
  934. { register unit in used units }
  935. pu.u:=loaded_unit;
  936. pu.loaded:=true;
  937. { doubles are not important for that list PM }
  938. pu.u.dependent_units.concat(tdependent_unit.create(self));
  939. { need to recompile the current unit ? }
  940. if loaded_unit.crc<>pu.checksum then
  941. begin
  942. Message2(unit_u_recompile_crc_change,realmodulename^,pu.realname^);
  943. recompile_reason:=rr_crcchanged;
  944. do_compile:=true;
  945. dispose(map);
  946. map:=nil;
  947. exit;
  948. end;
  949. { setup the map entry for deref }
  950. {$ifndef NEWMAP}
  951. map^[nextmapentry]:=loaded_unit.globalsymtable;
  952. {$else NEWMAP}
  953. map^[nextmapentry]:=loaded_unit;
  954. {$endif NEWMAP}
  955. inc(nextmapentry);
  956. if nextmapentry>maxunits then
  957. Message(unit_f_too_much_units);
  958. end;
  959. pu:=tused_unit(pu.next);
  960. end;
  961. { ok, now load the interface of this unit }
  962. if current_module<>self then
  963. internalerror(200208187);
  964. // current_module:=self;
  965. // SetCompileModule(current_module);
  966. globalsymtable:=tglobalsymtable.create(modulename^);
  967. tstoredsymtable(globalsymtable).ppuload(ppufile);
  968. { now only read the implementation uses }
  969. in_implementation:=true;
  970. pu:=tused_unit(used_units.first);
  971. while assigned(pu) do
  972. begin
  973. if (not pu.loaded) and (not pu.in_interface) then
  974. begin
  975. loaded_unit:=loadunit(pu.realname^,'');
  976. if compiled then
  977. exit;
  978. { register unit in used units }
  979. pu.u:=loaded_unit;
  980. pu.loaded:=true;
  981. { need to recompile the current unit ? }
  982. if (loaded_unit.interface_crc<>pu.interface_checksum) {and
  983. not(current_module.in_second_compile) } then
  984. begin
  985. Message2(unit_u_recompile_crc_change,realmodulename^,pu.realname^+' {impl}');
  986. recompile_reason:=rr_crcchanged;
  987. do_compile:=true;
  988. dispose(map);
  989. map:=nil;
  990. exit;
  991. end;
  992. { setup the map entry for deref }
  993. {$ifndef NEWMAP}
  994. map^[nextmapentry]:=loaded_unit.globalsymtable;
  995. {$else NEWMAP}
  996. map^[nextmapentry]:=loaded_unit;
  997. {$endif NEWMAP}
  998. inc(nextmapentry);
  999. if nextmapentry>maxunits then
  1000. Message(unit_f_too_much_units);
  1001. end;
  1002. pu:=tused_unit(pu.next);
  1003. end;
  1004. { read the implementation/objectdata part }
  1005. load_implementation;
  1006. { load browser info if stored }
  1007. if ((flags and uf_has_browser)<>0) and load_refs then
  1008. begin
  1009. if current_module<>self then
  1010. internalerror(200208188);
  1011. // current_module:=self;
  1012. load_symtable_refs;
  1013. end;
  1014. { remove the map, it's not needed anymore }
  1015. dispose(map);
  1016. map:=nil;
  1017. end;
  1018. procedure tppumodule.loadppu;
  1019. var
  1020. name : string;
  1021. begin
  1022. { load interface section }
  1023. if not do_compile then
  1024. load_interface;
  1025. { only load units when we don't recompile }
  1026. if not do_compile then
  1027. load_usedunits;
  1028. { recompile if set }
  1029. if do_compile then
  1030. begin
  1031. { we don't need the ppufile anymore }
  1032. if assigned(ppufile) then
  1033. begin
  1034. ppufile.free;
  1035. ppufile:=nil;
  1036. end;
  1037. { recompile the unit or give a fatal error if sources not available }
  1038. if not(sources_avail) and
  1039. not(sources_checked) then
  1040. if (not search_unit(modulename^,'',true))
  1041. and (length(modulename^)>8) then
  1042. search_unit(copy(modulename^,1,8),'',true);
  1043. if not(sources_avail) then
  1044. begin
  1045. if recompile_reason=rr_noppu then
  1046. Message1(unit_f_cant_find_ppu,modulename^)
  1047. else
  1048. Message1(unit_f_cant_compile_unit,modulename^);
  1049. end
  1050. else
  1051. begin
  1052. if in_compile then
  1053. begin
  1054. in_second_compile:=true;
  1055. Message1(parser_d_compiling_second_time,modulename^);
  1056. end;
  1057. name:=mainsource^;
  1058. { compile this module }
  1059. compile(name);
  1060. in_second_compile:=false;
  1061. end;
  1062. end;
  1063. if assigned(ppufile) then
  1064. begin
  1065. ppufile.closefile;
  1066. ppufile.free;
  1067. ppufile:=nil;
  1068. end;
  1069. end;
  1070. {*****************************************************************************
  1071. LoadUnit
  1072. *****************************************************************************}
  1073. function loadunit(const s : stringid;const fn:string) : tmodule;
  1074. const
  1075. ImplIntf : array[boolean] of string[15]=('interface','implementation');
  1076. var
  1077. st : tglobalsymtable;
  1078. second_time : boolean;
  1079. old_current_module,hp2 : tmodule;
  1080. hp : tppumodule;
  1081. scanner : tscannerfile;
  1082. dummy : tmodule;
  1083. ups : stringid;
  1084. begin
  1085. old_current_module:=current_module;
  1086. { we are loading a new module, save the state of the scanner
  1087. and reset scanner+module }
  1088. if assigned(current_scanner) then
  1089. current_scanner.tempcloseinputfile;
  1090. current_scanner:=nil;
  1091. current_module:=nil;
  1092. { Info }
  1093. Message3(unit_u_load_unit,old_current_module.modulename^,ImplIntf[old_current_module.in_implementation],s);
  1094. ups:=upper(s);
  1095. { unit not found }
  1096. st:=nil;
  1097. dummy:=nil;
  1098. { search all loaded units }
  1099. hp:=tppumodule(loaded_units.first);
  1100. while assigned(hp) do
  1101. begin
  1102. if hp.modulename^=ups then
  1103. begin
  1104. { forced to reload ? }
  1105. if hp.do_reload then
  1106. begin
  1107. hp.do_reload:=false;
  1108. break;
  1109. end;
  1110. { only check for units. The main program is also
  1111. as a unit in the loaded_units list. We simply need
  1112. to ignore this entry (PFV) }
  1113. if hp.is_unit then
  1114. begin
  1115. { the unit is already registered }
  1116. { and this means that the unit }
  1117. { is already compiled }
  1118. { else there is a cyclic unit use }
  1119. if assigned(hp.globalsymtable) then
  1120. st:=tglobalsymtable(hp.globalsymtable)
  1121. else
  1122. begin
  1123. { both units in interface ? }
  1124. if (not old_current_module.in_implementation) and
  1125. (not hp.in_implementation) then
  1126. begin
  1127. { check for a cycle }
  1128. hp2:=old_current_module.loaded_from;
  1129. while assigned(hp2) and (hp2<>hp) do
  1130. begin
  1131. if hp2.in_implementation then
  1132. hp2:=nil
  1133. else
  1134. hp2:=hp2.loaded_from;
  1135. end;
  1136. if assigned(hp2) then
  1137. Message2(unit_f_circular_unit_reference,old_current_module.modulename^,hp.modulename^);
  1138. end;
  1139. end;
  1140. break;
  1141. end;
  1142. end
  1143. else if copy(hp.modulename^,1,8)=ups then
  1144. dummy:=hp;
  1145. { the next unit }
  1146. hp:=tppumodule(hp.next);
  1147. end;
  1148. if assigned(dummy) and not assigned(hp) then
  1149. Message2(unit_w_unit_name_error,s,dummy.modulename^);
  1150. { the unit is not in the loaded units, we must load it first }
  1151. if (not assigned(st)) then
  1152. begin
  1153. if assigned(hp) then
  1154. begin
  1155. current_module:=hp;
  1156. { try to load the unit a second time first }
  1157. Message1(unit_u_second_load_unit,current_module.modulename^);
  1158. second_time:=true;
  1159. current_module.in_second_load:=true;
  1160. { remove the old unit }
  1161. loaded_units.remove(current_module);
  1162. current_module.reset;
  1163. { try to reopen ppu }
  1164. tppumodule(current_module).search_unit(s,fn,false);
  1165. end
  1166. else
  1167. { generates a new unit info record }
  1168. begin
  1169. current_module:=tppumodule.create(old_current_module,s,fn,true);
  1170. second_time:=false;
  1171. end;
  1172. { close old_current_ppu on system that are
  1173. short on file handles like DOS PM }
  1174. {$ifdef SHORT_ON_FILE_HANDLES}
  1175. if old_current_module.is_unit and
  1176. assigned(tppumodule(old_current_module).ppufile) then
  1177. tppumodule(old_current_module).ppufile.tempclose;
  1178. {$endif SHORT_ON_FILE_HANDLES}
  1179. { now we can register the unit }
  1180. current_module.loaded_from:=old_current_module;
  1181. loaded_units.insert(current_module);
  1182. { now realy load the ppu }
  1183. tppumodule(current_module).loadppu;
  1184. { set compiled flag }
  1185. current_module.compiled:=true;
  1186. { load return pointer }
  1187. hp:=tppumodule(current_module);
  1188. { for a second_time recompile reload all dependent units,
  1189. for a first time compile register the unit _once_ }
  1190. if second_time then
  1191. begin
  1192. { now reload all dependent units }
  1193. hp2:=tmodule(loaded_units.first);
  1194. while assigned(hp2) do
  1195. begin
  1196. if hp2.do_reload then
  1197. dummy:=loadunit(hp2.modulename^,'');
  1198. hp2:=tmodule(hp2.next);
  1199. end;
  1200. end
  1201. else
  1202. usedunits.concat(tused_unit.create(current_module,true));
  1203. end;
  1204. { set the old module }
  1205. {$ifdef SHORT_ON_FILE_HANDLES}
  1206. if old_current_module.is_unit and
  1207. assigned(tppumodule(old_current_module).ppufile) then
  1208. tppumodule(old_current_module).ppufile.tempopen;
  1209. {$endif SHORT_ON_FILE_HANDLES}
  1210. { we are back, restore current_module and current_scanner }
  1211. current_module:=old_current_module;
  1212. current_scanner:=tscannerfile(current_module.scanner);
  1213. if assigned(current_scanner) then
  1214. current_scanner.tempopeninputfile;
  1215. SetCompileModule(current_module);
  1216. loadunit:=hp;
  1217. end;
  1218. end.
  1219. {
  1220. $Log$
  1221. Revision 1.27 2002-11-20 12:36:24 mazen
  1222. * $UNITPATH directive is now working
  1223. Revision 1.26 2002/11/15 01:58:46 peter
  1224. * merged changes from 1.0.7 up to 04-11
  1225. - -V option for generating bug report tracing
  1226. - more tracing for option parsing
  1227. - errors for cdecl and high()
  1228. - win32 import stabs
  1229. - win32 records<=8 are returned in eax:edx (turned off by default)
  1230. - heaptrc update
  1231. - more info for temp management in .s file with EXTDEBUG
  1232. Revision 1.25 2002/10/20 14:49:31 peter
  1233. * store original source time in ppu so it can be compared instead of
  1234. comparing with the ppu time
  1235. Revision 1.24 2002/10/04 20:13:10 peter
  1236. * set in_second_load flag before resetting the module, this is
  1237. required to skip some checkings
  1238. Revision 1.23 2002/08/19 19:36:42 peter
  1239. * More fixes for cross unit inlining, all tnodes are now implemented
  1240. * Moved pocall_internconst to po_internconst because it is not a
  1241. calling type at all and it conflicted when inlining of these small
  1242. functions was requested
  1243. Revision 1.22 2002/08/18 19:58:28 peter
  1244. * more current_scanner fixes
  1245. Revision 1.21 2002/08/15 15:09:41 carl
  1246. + fpu emulation helpers (ppu checking also)
  1247. Revision 1.20 2002/08/12 16:46:04 peter
  1248. * tscannerfile is now destroyed in tmodule.reset and current_scanner
  1249. is updated accordingly. This removes all the loading and saving of
  1250. the old scanner and the invalid flag marking
  1251. Revision 1.19 2002/08/11 14:28:19 peter
  1252. * TScannerFile.SetInvalid added that will also reset inputfile
  1253. Revision 1.18 2002/08/11 13:24:11 peter
  1254. * saving of asmsymbols in ppu supported
  1255. * asmsymbollist global is removed and moved into a new class
  1256. tasmlibrarydata that will hold the info of a .a file which
  1257. corresponds with a single module. Added librarydata to tmodule
  1258. to keep the library info stored for the module. In the future the
  1259. objectfiles will also be stored to the tasmlibrarydata class
  1260. * all getlabel/newasmsymbol and friends are moved to the new class
  1261. Revision 1.17 2002/07/26 21:15:37 florian
  1262. * rewrote the system handling
  1263. Revision 1.16 2002/05/16 19:46:36 carl
  1264. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1265. + try to fix temp allocation (still in ifdef)
  1266. + generic constructor calls
  1267. + start of tassembler / tmodulebase class cleanup
  1268. Revision 1.15 2002/05/14 19:34:41 peter
  1269. * removed old logs and updated copyright year
  1270. Revision 1.14 2002/05/12 16:53:05 peter
  1271. * moved entry and exitcode to ncgutil and cgobj
  1272. * foreach gets extra argument for passing local data to the
  1273. iterator function
  1274. * -CR checks also class typecasts at runtime by changing them
  1275. into as
  1276. * fixed compiler to cycle with the -CR option
  1277. * fixed stabs with elf writer, finally the global variables can
  1278. be watched
  1279. * removed a lot of routines from cga unit and replaced them by
  1280. calls to cgobj
  1281. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1282. u32bit then the other is typecasted also to u32bit without giving
  1283. a rangecheck warning/error.
  1284. * fixed pascal calling method with reversing also the high tree in
  1285. the parast, detected by tcalcst3 test
  1286. Revision 1.13 2002/04/04 19:05:56 peter
  1287. * removed unused units
  1288. * use tlocation.size in cg.a_*loc*() routines
  1289. Revision 1.12 2002/03/28 20:46:44 carl
  1290. - remove go32v1 support
  1291. Revision 1.11 2002/01/19 14:20:13 peter
  1292. * check for -Un when loading ppu with wrong name
  1293. }