pmodules.pas 68 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl
  3. Handles the parsing and loading of the modules (ppufiles)
  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 pmodules;
  18. {$i fpcdefs.inc}
  19. interface
  20. procedure proc_unit;
  21. procedure proc_package;
  22. procedure proc_program(islibrary : boolean);
  23. implementation
  24. uses
  25. SysUtils,
  26. globtype,version,systems,tokens,
  27. cutils,cfileutl,cclasses,comphook,
  28. globals,verbose,fmodule,finput,fppu,
  29. symconst,symbase,symtype,symdef,symsym,symtable,
  30. aasmtai,aasmdata,aasmcpu,aasmbase,
  31. cgbase,cgobj,
  32. nbas,ncgutil,
  33. link,assemble,import,export,gendef,ppu,comprsrc,dbgbase,
  34. cresstr,procinfo,
  35. pexports,
  36. scanner,pbase,pexpr,psystem,psub,pdecsub,ptype;
  37. procedure create_objectfile;
  38. var
  39. DLLScanner : TDLLScanner;
  40. s : string;
  41. KeepShared : TCmdStrList;
  42. begin
  43. { try to create import entries from system dlls }
  44. if (tf_has_dllscanner in target_info.flags) and
  45. (not current_module.linkOtherSharedLibs.Empty) then
  46. begin
  47. { Init DLLScanner }
  48. if assigned(CDLLScanner[target_info.system]) then
  49. DLLScanner:=CDLLScanner[target_info.system].Create
  50. else
  51. internalerror(200104121);
  52. KeepShared:=TCmdStrList.Create;
  53. { Walk all shared libs }
  54. While not current_module.linkOtherSharedLibs.Empty do
  55. begin
  56. S:=current_module.linkOtherSharedLibs.Getusemask(link_always);
  57. if not DLLScanner.scan(s) then
  58. KeepShared.Concat(s);
  59. end;
  60. DLLscanner.Free;
  61. { Recreate import section }
  62. if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
  63. begin
  64. if assigned(current_asmdata.asmlists[al_imports]) then
  65. current_asmdata.asmlists[al_imports].clear
  66. else
  67. current_asmdata.asmlists[al_imports]:=TAsmList.Create;
  68. importlib.generatelib;
  69. end;
  70. { Readd the not processed files }
  71. while not KeepShared.Empty do
  72. begin
  73. s:=KeepShared.GetFirst;
  74. current_module.linkOtherSharedLibs.add(s,link_always);
  75. end;
  76. KeepShared.Free;
  77. end;
  78. { Start and end module debuginfo, at least required for stabs
  79. to insert n_sourcefile lines }
  80. if (cs_debuginfo in current_settings.moduleswitches) or
  81. (cs_use_lineinfo in current_settings.globalswitches) then
  82. current_debuginfo.insertmoduleinfo;
  83. { create the .s file and assemble it }
  84. GenerateAsm(false);
  85. { Also create a smartlinked version ? }
  86. if create_smartlink_library then
  87. begin
  88. GenerateAsm(true);
  89. if (af_needar in target_asm.flags) then
  90. Linker.MakeStaticLibrary;
  91. end;
  92. { resource files }
  93. CompileResourceFiles;
  94. end;
  95. procedure insertobjectfile;
  96. { Insert the used object file for this unit in the used list for this unit }
  97. begin
  98. current_module.linkunitofiles.add(current_module.objfilename^,link_static);
  99. current_module.flags:=current_module.flags or uf_static_linked;
  100. if create_smartlink_library then
  101. begin
  102. current_module.linkunitstaticlibs.add(current_module.staticlibfilename^,link_smart);
  103. current_module.flags:=current_module.flags or uf_smart_linked;
  104. end;
  105. end;
  106. procedure create_dwarf;
  107. begin
  108. { Dwarf conflicts with smartlinking in separate .a files }
  109. if create_smartlink_library then
  110. exit;
  111. { Call frame information }
  112. if (tf_needs_dwarf_cfi in target_info.flags) and
  113. (af_supports_dwarf in target_asm.flags) then
  114. begin
  115. current_asmdata.asmlists[al_dwarf]:=TAsmList.create;
  116. current_asmdata.asmcfi.generate_code(current_asmdata.asmlists[al_dwarf]);
  117. end;
  118. end;
  119. procedure InsertThreadvarTablesTable;
  120. var
  121. hp : tused_unit;
  122. ltvTables : TAsmList;
  123. count : longint;
  124. begin
  125. if (tf_section_threadvars in target_info.flags) then
  126. exit;
  127. ltvTables:=TAsmList.Create;
  128. count:=0;
  129. hp:=tused_unit(usedunits.first);
  130. while assigned(hp) do
  131. begin
  132. If (hp.u.flags and uf_threadvars)=uf_threadvars then
  133. begin
  134. ltvTables.concat(Tai_const.Createname(make_mangledname('THREADVARLIST',hp.u.globalsymtable,''),0));
  135. inc(count);
  136. end;
  137. hp:=tused_unit(hp.next);
  138. end;
  139. { Add program threadvars, if any }
  140. If (current_module.flags and uf_threadvars)=uf_threadvars then
  141. begin
  142. ltvTables.concat(Tai_const.Createname(make_mangledname('THREADVARLIST',current_module.localsymtable,''),0));
  143. inc(count);
  144. end;
  145. { Insert TableCount at start }
  146. ltvTables.insert(Tai_const.Create_32bit(count));
  147. { insert in data segment }
  148. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  149. new_section(current_asmdata.asmlists[al_globals],sec_data,'FPC_THREADVARTABLES',sizeof(aint));
  150. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('FPC_THREADVARTABLES',AT_DATA,0));
  151. current_asmdata.asmlists[al_globals].concatlist(ltvTables);
  152. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('FPC_THREADVARTABLES'));
  153. ltvTables.free;
  154. end;
  155. procedure AddToThreadvarList(p:TObject;arg:pointer);
  156. var
  157. ltvTable : TAsmList;
  158. begin
  159. ltvTable:=TAsmList(arg);
  160. if (tsym(p).typ=staticvarsym) and
  161. (vo_is_thread_var in tstaticvarsym(p).varoptions) then
  162. begin
  163. { address of threadvar }
  164. ltvTable.concat(tai_const.Createname(tstaticvarsym(p).mangledname,0));
  165. { size of threadvar }
  166. ltvTable.concat(tai_const.create_32bit(tstaticvarsym(p).getsize));
  167. end;
  168. end;
  169. procedure InsertThreadvars;
  170. var
  171. s : string;
  172. ltvTable : TAsmList;
  173. begin
  174. if (tf_section_threadvars in target_info.flags) then
  175. exit;
  176. ltvTable:=TAsmList.create;
  177. if assigned(current_module.globalsymtable) then
  178. current_module.globalsymtable.SymList.ForEachCall(@AddToThreadvarList,ltvTable);
  179. current_module.localsymtable.SymList.ForEachCall(@AddToThreadvarList,ltvTable);
  180. if ltvTable.first<>nil then
  181. begin
  182. s:=make_mangledname('THREADVARLIST',current_module.localsymtable,'');
  183. { end of the list marker }
  184. ltvTable.concat(tai_const.create_sym(nil));
  185. { add to datasegment }
  186. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  187. new_section(current_asmdata.asmlists[al_globals],sec_data,s,sizeof(aint));
  188. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global(s,AT_DATA,0));
  189. current_asmdata.asmlists[al_globals].concatlist(ltvTable);
  190. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname(s));
  191. current_module.flags:=current_module.flags or uf_threadvars;
  192. end;
  193. ltvTable.Free;
  194. end;
  195. Procedure InsertResourceInfo;
  196. var
  197. hp : tused_unit;
  198. found : Boolean;
  199. I : Integer;
  200. ResourceInfo : TAsmList;
  201. begin
  202. if target_res.id=res_elf then
  203. begin
  204. hp:=tused_unit(usedunits.first);
  205. found:=false;
  206. Found:=((current_module.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
  207. If not found then
  208. While Assigned(hp) and not Found do
  209. begin
  210. Found:=((hp.u.flags and uf_has_resourcefiles)=uf_has_resourcefiles);
  211. hp:=tused_unit(hp.next);
  212. end;
  213. ResourceInfo:=TAsmList.Create;
  214. if found then
  215. begin
  216. { Valid pointer to resource information }
  217. ResourceInfo.concat(Tai_symbol.Createname_global('FPC_RESLOCATION',AT_DATA,0));
  218. ResourceInfo.concat(Tai_const.Createname('FPC_RESSYMBOL',0));
  219. {$ifdef EXTERNALRESPTRS}
  220. current_module.linkotherofiles.add('resptrs.o',link_always);
  221. {$else EXTERNALRESPTRS}
  222. new_section(ResourceInfo,sec_fpc,'resptrs',4);
  223. ResourceInfo.concat(Tai_symbol.Createname_global('FPC_RESSYMBOL',AT_DATA,0));
  224. For I:=1 to 32 do
  225. ResourceInfo.Concat(Tai_const.Create_32bit(0));
  226. {$endif EXTERNALRESPTRS}
  227. end
  228. else
  229. begin
  230. { Nil pointer to resource information }
  231. ResourceInfo.concat(Tai_symbol.Createname_global('FPC_RESLOCATION',AT_DATA,0));
  232. ResourceInfo.Concat(Tai_const.Create_32bit(0));
  233. end;
  234. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  235. current_asmdata.asmlists[al_globals].concatlist(ResourceInfo);
  236. ResourceInfo.free;
  237. end;
  238. end;
  239. Procedure InsertResourceTablesTable;
  240. var
  241. hp : tmodule;
  242. ResourceStringTables : tasmlist;
  243. count : longint;
  244. begin
  245. ResourceStringTables:=tasmlist.Create;
  246. count:=0;
  247. hp:=tmodule(loaded_units.first);
  248. while assigned(hp) do
  249. begin
  250. If (hp.flags and uf_has_resourcestrings)=uf_has_resourcestrings then
  251. begin
  252. ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'START'),0));
  253. ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'END'),0));
  254. inc(count);
  255. end;
  256. hp:=tmodule(hp.next);
  257. end;
  258. { Insert TableCount at start }
  259. ResourceStringTables.insert(Tai_const.Create_aint(count));
  260. { Add to data segment }
  261. maybe_new_object_file(current_asmdata.AsmLists[al_globals]);
  262. new_section(current_asmdata.AsmLists[al_globals],sec_data,'FPC_RESOURCESTRINGTABLES',sizeof(aint));
  263. current_asmdata.AsmLists[al_globals].concat(Tai_symbol.Createname_global('FPC_RESOURCESTRINGTABLES',AT_DATA,0));
  264. current_asmdata.AsmLists[al_globals].concatlist(ResourceStringTables);
  265. current_asmdata.AsmLists[al_globals].concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
  266. ResourceStringTables.free;
  267. end;
  268. procedure InsertInitFinalTable;
  269. var
  270. hp : tused_unit;
  271. unitinits : TAsmList;
  272. count : longint;
  273. begin
  274. unitinits:=TAsmList.Create;
  275. count:=0;
  276. hp:=tused_unit(usedunits.first);
  277. while assigned(hp) do
  278. begin
  279. { call the unit init code and make it external }
  280. if (hp.u.flags and (uf_init or uf_finalize))<>0 then
  281. begin
  282. if (hp.u.flags and uf_init)<>0 then
  283. unitinits.concat(Tai_const.Createname(make_mangledname('INIT$',hp.u.globalsymtable,''),0))
  284. else
  285. unitinits.concat(Tai_const.Create_sym(nil));
  286. if (hp.u.flags and uf_finalize)<>0 then
  287. unitinits.concat(Tai_const.Createname(make_mangledname('FINALIZE$',hp.u.globalsymtable,''),0))
  288. else
  289. unitinits.concat(Tai_const.Create_sym(nil));
  290. inc(count);
  291. end;
  292. hp:=tused_unit(hp.next);
  293. end;
  294. { Insert initialization/finalization of the program }
  295. if (current_module.flags and (uf_init or uf_finalize))<>0 then
  296. begin
  297. if (current_module.flags and uf_init)<>0 then
  298. unitinits.concat(Tai_const.Createname(make_mangledname('INIT$',current_module.localsymtable,''),0))
  299. else
  300. unitinits.concat(Tai_const.Create_sym(nil));
  301. if (current_module.flags and uf_finalize)<>0 then
  302. unitinits.concat(Tai_const.Createname(make_mangledname('FINALIZE$',current_module.localsymtable,''),0))
  303. else
  304. unitinits.concat(Tai_const.Create_sym(nil));
  305. inc(count);
  306. end;
  307. { Insert TableCount,InitCount at start }
  308. unitinits.insert(Tai_const.Create_32bit(0));
  309. unitinits.insert(Tai_const.Create_32bit(count));
  310. { Add to data segment }
  311. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  312. new_section(current_asmdata.asmlists[al_globals],sec_data,'INITFINAL',sizeof(aint));
  313. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('INITFINAL',AT_DATA,0));
  314. current_asmdata.asmlists[al_globals].concatlist(unitinits);
  315. current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('INITFINAL'));
  316. unitinits.free;
  317. end;
  318. procedure insertmemorysizes;
  319. {$IFDEF POWERPC}
  320. var
  321. stkcookie: string;
  322. {$ENDIF POWERPC}
  323. begin
  324. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  325. { Insert Ident of the compiler in the .fpc.version section }
  326. current_asmdata.asmlists[al_globals].concat(Tai_section.create(sec_fpc,'version',0));
  327. current_asmdata.asmlists[al_globals].concat(Tai_align.Create(const_align(32)));
  328. current_asmdata.asmlists[al_globals].concat(Tai_string.Create('FPC '+full_version_string+
  329. ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname));
  330. if not(tf_no_generic_stackcheck in target_info.flags) then
  331. begin
  332. { stacksize can be specified and is now simulated }
  333. new_section(current_asmdata.asmlists[al_globals],sec_data,'__stklen', sizeof(aint));
  334. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__stklen',AT_DATA,sizeof(aint)));
  335. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(stacksize));
  336. end;
  337. {$IFDEF POWERPC}
  338. { AmigaOS4 "stack cookie" support }
  339. if ( target_info.system = system_powerpc_amiga ) then
  340. begin
  341. { this symbol is needed to ignite powerpc amigaos' }
  342. { stack allocation magic for us with the given stack size. }
  343. { note: won't work for m68k amigaos or morphos. (KB) }
  344. str(stacksize,stkcookie);
  345. stkcookie:='$STACK: '+stkcookie+#0;
  346. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  347. new_section(current_asmdata.asmlists[al_globals],sec_data,'__stack_cookie',length(stkcookie));
  348. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__stack_cookie',AT_DATA,length(stkcookie)));
  349. current_asmdata.asmlists[al_globals].concat(Tai_string.Create(stkcookie));
  350. end;
  351. {$ENDIF POWERPC}
  352. { Initial heapsize }
  353. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  354. new_section(current_asmdata.asmlists[al_globals],sec_data,'__heapsize',sizeof(aint));
  355. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__heapsize',AT_DATA,sizeof(aint)));
  356. current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(heapsize));
  357. { Initial heapsize }
  358. maybe_new_object_file(current_asmdata.asmlists[al_globals]);
  359. new_section(current_asmdata.asmlists[al_globals],sec_data,'__fpc_valgrind',sizeof(boolean));
  360. current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('__fpc_valgrind',AT_DATA,sizeof(boolean)));
  361. current_asmdata.asmlists[al_globals].concat(Tai_const.create_8bit(byte(cs_gdb_valgrind in current_settings.globalswitches)));
  362. end;
  363. procedure AddUnit(const s:string);
  364. var
  365. hp : tppumodule;
  366. unitsym : tunitsym;
  367. begin
  368. { load unit }
  369. hp:=registerunit(current_module,s,'');
  370. hp.loadppu;
  371. hp.adddependency(current_module);
  372. { add to symtable stack }
  373. symtablestack.push(hp.globalsymtable);
  374. if (m_mac in current_settings.modeswitches) and
  375. assigned(hp.globalmacrosymtable) then
  376. macrosymtablestack.push(hp.globalmacrosymtable);
  377. { insert unitsym }
  378. unitsym:=tunitsym.create(s,hp);
  379. inc(unitsym.refs);
  380. current_module.localsymtable.insert(unitsym);
  381. { add to used units }
  382. current_module.addusedunit(hp,false,unitsym);
  383. end;
  384. procedure maybeloadvariantsunit;
  385. var
  386. hp : tmodule;
  387. begin
  388. { Do we need the variants unit? Skip this
  389. for VarUtils unit for bootstrapping }
  390. if (current_module.flags and uf_uses_variants=0) or
  391. (current_module.modulename^='VARUTILS') then
  392. exit;
  393. { Variants unit already loaded? }
  394. hp:=tmodule(loaded_units.first);
  395. while assigned(hp) do
  396. begin
  397. if hp.modulename^='VARIANTS' then
  398. exit;
  399. hp:=tmodule(hp.next);
  400. end;
  401. { Variants unit is not loaded yet, load it now }
  402. Message(parser_w_implicit_uses_of_variants_unit);
  403. AddUnit('variants');
  404. end;
  405. procedure loaddefaultunits;
  406. begin
  407. { we are going to rebuild the symtablestack, clear it first }
  408. symtablestack.clear;
  409. macrosymtablestack.clear;
  410. { macro symtable }
  411. macrosymtablestack.push(initialmacrosymtable);
  412. { are we compiling the system unit? }
  413. if (cs_compilesystem in current_settings.moduleswitches) then
  414. begin
  415. systemunit:=tglobalsymtable(current_module.localsymtable);
  416. { create system defines }
  417. create_intern_symbols;
  418. create_intern_types;
  419. { Set the owner of errorsym and errortype to symtable to
  420. prevent crashes when accessing .owner }
  421. generrorsym.owner:=systemunit;
  422. generrordef.owner:=systemunit;
  423. exit;
  424. end;
  425. { insert the system unit, it is allways the first. Load also the
  426. internal types from the system unit }
  427. AddUnit('system');
  428. systemunit:=tglobalsymtable(symtablestack.top);
  429. load_intern_types;
  430. { Set the owner of errorsym and errortype to symtable to
  431. prevent crashes when accessing .owner }
  432. generrorsym.owner:=systemunit;
  433. generrordef.owner:=systemunit;
  434. { Units only required for main module }
  435. if not(current_module.is_unit) then
  436. begin
  437. { Heaptrc unit, load heaptrace before any other units especially objpas }
  438. if (cs_use_heaptrc in current_settings.globalswitches) then
  439. AddUnit('heaptrc');
  440. { Lineinfo unit }
  441. if (cs_use_lineinfo in current_settings.globalswitches) then begin
  442. if (paratargetdbg = dbg_stabs) then
  443. AddUnit('lineinfo')
  444. else
  445. AddUnit('lnfodwrf');
  446. end;
  447. { Valgrind requires c memory manager }
  448. if (cs_gdb_valgrind in current_settings.globalswitches) then
  449. AddUnit('cmem');
  450. {$ifdef cpufpemu}
  451. { Floating point emulation unit?
  452. softfpu must be in the system unit anyways (FK)
  453. if (cs_fp_emulation in current_settings.moduleswitches) and not(target_info.system in system_wince) then
  454. AddUnit('softfpu');
  455. }
  456. {$endif cpufpemu}
  457. end;
  458. { Objpas unit? }
  459. if m_objpas in current_settings.modeswitches then
  460. AddUnit('objpas');
  461. { Macpas unit? }
  462. if m_mac in current_settings.modeswitches then
  463. AddUnit('macpas');
  464. { Profile unit? Needed for go32v2 only }
  465. if (cs_profile in current_settings.moduleswitches) and
  466. (target_info.system in [system_i386_go32v2,system_i386_watcom]) then
  467. AddUnit('profile');
  468. if (cs_load_fpcylix_unit in current_settings.globalswitches) then
  469. begin
  470. AddUnit('fpcylix');
  471. AddUnit('dynlibs');
  472. end;
  473. end;
  474. procedure loadautounits;
  475. var
  476. hs,s : string;
  477. begin
  478. hs:=autoloadunits;
  479. repeat
  480. s:=GetToken(hs,',');
  481. if s='' then
  482. break;
  483. AddUnit(s);
  484. until false;
  485. end;
  486. procedure loadunits;
  487. var
  488. s,sorg : TIDString;
  489. fn : string;
  490. pu : tused_unit;
  491. hp2 : tmodule;
  492. unitsym : tunitsym;
  493. begin
  494. consume(_USES);
  495. repeat
  496. s:=pattern;
  497. sorg:=orgpattern;
  498. consume(_ID);
  499. { support "<unit> in '<file>'" construct, but not for tp7 }
  500. fn:='';
  501. if not(m_tp7 in current_settings.modeswitches) and
  502. try_to_consume(_OP_IN) then
  503. fn:=FixFileName(get_stringconst);
  504. { Give a warning if lineinfo is loaded }
  505. if s='LINEINFO' then begin
  506. Message(parser_w_no_lineinfo_use_switch);
  507. if (paratargetdbg in [dbg_dwarf2, dbg_dwarf3]) then
  508. s := 'LNFODWRF';
  509. sorg := s;
  510. end;
  511. { Give a warning if objpas is loaded }
  512. if s='OBJPAS' then
  513. Message(parser_w_no_objpas_use_mode);
  514. { Using the unit itself is not possible }
  515. if (s<>current_module.modulename^) then
  516. begin
  517. { check if the unit is already used }
  518. hp2:=nil;
  519. pu:=tused_unit(current_module.used_units.first);
  520. while assigned(pu) do
  521. begin
  522. if (pu.u.modulename^=s) then
  523. begin
  524. hp2:=pu.u;
  525. break;
  526. end;
  527. pu:=tused_unit(pu.next);
  528. end;
  529. if not assigned(hp2) then
  530. hp2:=registerunit(current_module,sorg,fn)
  531. else
  532. Message1(sym_e_duplicate_id,s);
  533. { Create unitsym, we need to use the name as specified, we
  534. can not use the modulename because that can be different
  535. when -Un is used }
  536. unitsym:=tunitsym.create(sorg,nil);
  537. current_module.localsymtable.insert(unitsym);
  538. { the current module uses the unit hp2 }
  539. current_module.addusedunit(hp2,true,unitsym);
  540. end
  541. else
  542. Message1(sym_e_duplicate_id,s);
  543. if token=_COMMA then
  544. begin
  545. pattern:='';
  546. consume(_COMMA);
  547. end
  548. else
  549. break;
  550. until false;
  551. { Load the units }
  552. pu:=tused_unit(current_module.used_units.first);
  553. while assigned(pu) do
  554. begin
  555. { Only load the units that are in the current
  556. (interface/implementation) uses clause }
  557. if pu.in_uses and
  558. (pu.in_interface=current_module.in_interface) then
  559. begin
  560. tppumodule(pu.u).loadppu;
  561. { is our module compiled? then we can stop }
  562. if current_module.state=ms_compiled then
  563. exit;
  564. { add this unit to the dependencies }
  565. pu.u.adddependency(current_module);
  566. { save crc values }
  567. pu.checksum:=pu.u.crc;
  568. pu.interface_checksum:=pu.u.interface_crc;
  569. { connect unitsym to the module }
  570. pu.unitsym.module:=pu.u;
  571. { add to symtable stack }
  572. symtablestack.push(pu.u.globalsymtable);
  573. if (m_mac in current_settings.modeswitches) and
  574. assigned(pu.u.globalmacrosymtable) then
  575. macrosymtablestack.push(pu.u.globalmacrosymtable);
  576. end;
  577. pu:=tused_unit(pu.next);
  578. end;
  579. consume(_SEMICOLON);
  580. end;
  581. procedure reset_all_defs;
  582. procedure reset_used_unit_defs(hp:tmodule);
  583. var
  584. pu : tused_unit;
  585. begin
  586. pu:=tused_unit(hp.used_units.first);
  587. while assigned(pu) do
  588. begin
  589. if not pu.u.is_reset then
  590. begin
  591. { prevent infinte loop for circular dependencies }
  592. pu.u.is_reset:=true;
  593. if assigned(pu.u.globalsymtable) then
  594. begin
  595. tglobalsymtable(pu.u.globalsymtable).reset_all_defs;
  596. reset_used_unit_defs(pu.u);
  597. end;
  598. end;
  599. pu:=tused_unit(pu.next);
  600. end;
  601. end;
  602. var
  603. hp2 : tmodule;
  604. begin
  605. hp2:=tmodule(loaded_units.first);
  606. while assigned(hp2) do
  607. begin
  608. hp2.is_reset:=false;
  609. hp2:=tmodule(hp2.next);
  610. end;
  611. reset_used_unit_defs(current_module);
  612. end;
  613. procedure free_localsymtables(st:TSymtable);
  614. var
  615. i : longint;
  616. def : tstoreddef;
  617. pd : tprocdef;
  618. begin
  619. for i:=0 to st.DefList.Count-1 do
  620. begin
  621. def:=tstoreddef(st.DefList[i]);
  622. if def.typ=procdef then
  623. begin
  624. pd:=tprocdef(def);
  625. if assigned(pd.localst) and
  626. (pd.localst.symtabletype<>staticsymtable) and
  627. not(po_inline in pd.procoptions) then
  628. begin
  629. free_localsymtables(pd.localst);
  630. pd.localst.free;
  631. pd.localst:=nil;
  632. end;
  633. end;
  634. end;
  635. end;
  636. procedure parse_implementation_uses;
  637. begin
  638. if token=_USES then
  639. loadunits;
  640. end;
  641. procedure setupglobalswitches;
  642. begin
  643. if (cs_create_pic in current_settings.moduleswitches) then
  644. begin
  645. def_system_macro('FPC_PIC');
  646. def_system_macro('PIC');
  647. end;
  648. end;
  649. function create_main_proc(const name:string;potype:tproctypeoption;st:TSymtable):tcgprocinfo;
  650. var
  651. ps : tprocsym;
  652. pd : tprocdef;
  653. begin
  654. { there should be no current_procinfo available }
  655. if assigned(current_procinfo) then
  656. internalerror(200304275);
  657. {Generate a procsym for main}
  658. ps:=tprocsym.create('$'+name);
  659. { main are allways used }
  660. inc(ps.refs);
  661. st.insert(ps);
  662. pd:=tprocdef.create(main_program_level);
  663. include(pd.procoptions,po_global);
  664. pd.procsym:=ps;
  665. ps.ProcdefList.Add(pd);
  666. { set procdef options }
  667. pd.proctypeoption:=potype;
  668. pd.proccalloption:=pocall_default;
  669. include(pd.procoptions,po_hascallingconvention);
  670. pd.forwarddef:=false;
  671. pd.setmangledname(target_info.cprefix+name);
  672. pd.aliasnames.insert(pd.mangledname);
  673. handle_calling_convention(pd);
  674. { We don't need is a local symtable. Change it into the static
  675. symtable }
  676. pd.localst.free;
  677. pd.localst:=st;
  678. { set procinfo and current_procinfo.procdef }
  679. result:=tcgprocinfo(cprocinfo.create(nil));
  680. result.procdef:=pd;
  681. { main proc does always a call e.g. to init system unit }
  682. include(result.flags,pi_do_call);
  683. end;
  684. procedure release_main_proc(pi:tcgprocinfo);
  685. begin
  686. { remove localst as it was replaced by staticsymtable }
  687. pi.procdef.localst:=nil;
  688. { remove procinfo }
  689. current_module.procinfo:=nil;
  690. pi.free;
  691. pi:=nil;
  692. end;
  693. function gen_implicit_initfinal(flag:word;st:TSymtable):tcgprocinfo;
  694. begin
  695. { update module flags }
  696. current_module.flags:=current_module.flags or flag;
  697. { create procdef }
  698. case flag of
  699. uf_init :
  700. begin
  701. result:=create_main_proc(make_mangledname('',current_module.localsymtable,'init_implicit'),potype_unitinit,st);
  702. result.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
  703. end;
  704. uf_finalize :
  705. begin
  706. result:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize_implicit'),potype_unitfinalize,st);
  707. result.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  708. if (not current_module.is_unit) then
  709. result.procdef.aliasnames.insert('PASCALFINALIZE');
  710. end;
  711. else
  712. internalerror(200304253);
  713. end;
  714. result.code:=cnothingnode.create;
  715. end;
  716. procedure copy_macro(p:TObject; arg:pointer);
  717. begin
  718. current_module.globalmacrosymtable.insert(tmacro(p).getcopy);
  719. end;
  720. procedure proc_unit;
  721. function is_assembler_generated:boolean;
  722. var
  723. hal : tasmlisttype;
  724. begin
  725. result:=false;
  726. if Errorcount=0 then
  727. begin
  728. for hal:=low(TasmlistType) to high(TasmlistType) do
  729. if not current_asmdata.asmlists[hal].empty then
  730. begin
  731. result:=true;
  732. exit;
  733. end;
  734. end;
  735. end;
  736. var
  737. main_file: tinputfile;
  738. {$ifdef EXTDEBUG}
  739. store_crc,
  740. {$endif EXTDEBUG}
  741. store_interface_crc : cardinal;
  742. s1,s2 : ^string; {Saves stack space}
  743. force_init_final : boolean;
  744. init_procinfo,
  745. finalize_procinfo : tcgprocinfo;
  746. unitname8 : string[8];
  747. has_impl,ag: boolean;
  748. {$ifdef i386}
  749. gotvarsym : tstaticvarsym;
  750. {$endif i386}
  751. begin
  752. init_procinfo:=nil;
  753. finalize_procinfo:=nil;
  754. if m_mac in current_settings.modeswitches then
  755. current_module.mode_switch_allowed:= false;
  756. consume(_UNIT);
  757. if compile_level=1 then
  758. Status.IsExe:=false;
  759. if token=_ID then
  760. begin
  761. { create filenames and unit name }
  762. main_file := current_scanner.inputfile;
  763. while assigned(main_file.next) do
  764. main_file := main_file.next;
  765. new(s1);
  766. s1^:=current_module.modulename^;
  767. current_module.SetFileName(main_file.path^+main_file.name^,true);
  768. current_module.SetModuleName(orgpattern);
  769. { check for system unit }
  770. new(s2);
  771. s2^:=upper(ChangeFileExt(ExtractFileName(main_file.name^),''));
  772. unitname8:=copy(current_module.modulename^,1,8);
  773. if (cs_check_unit_name in current_settings.globalswitches) and
  774. (
  775. not(
  776. (current_module.modulename^=s2^) or
  777. (
  778. (length(current_module.modulename^)>8) and
  779. (unitname8=s2^)
  780. )
  781. )
  782. or
  783. (
  784. (length(s1^)>8) and
  785. (s1^<>current_module.modulename^)
  786. )
  787. ) then
  788. Message1(unit_e_illegal_unit_name,current_module.realmodulename^);
  789. if (current_module.modulename^='SYSTEM') then
  790. include(current_settings.moduleswitches,cs_compilesystem);
  791. dispose(s2);
  792. dispose(s1);
  793. end;
  794. if (target_info.system in system_unit_program_exports) then
  795. exportlib.preparelib(current_module.realmodulename^);
  796. consume(_ID);
  797. consume(_SEMICOLON);
  798. consume(_INTERFACE);
  799. { global switches are read, so further changes aren't allowed }
  800. current_module.in_global:=false;
  801. { handle the global switches }
  802. setupglobalswitches;
  803. message1(unit_u_loading_interface_units,current_module.modulename^);
  804. { update status }
  805. status.currentmodule:=current_module.realmodulename^;
  806. { maybe turn off m_objpas if we are compiling objpas }
  807. if (current_module.modulename^='OBJPAS') then
  808. exclude(current_settings.modeswitches,m_objpas);
  809. { maybe turn off m_mac if we are compiling macpas }
  810. if (current_module.modulename^='MACPAS') then
  811. exclude(current_settings.modeswitches,m_mac);
  812. parse_only:=true;
  813. { generate now the global symboltable,
  814. define first as local to overcome dependency conflicts }
  815. current_module.localsymtable:=tglobalsymtable.create(current_module.modulename^,current_module.moduleid);
  816. { insert unitsym of this unit to prevent other units having
  817. the same name }
  818. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  819. { load default units, like the system unit }
  820. loaddefaultunits;
  821. { insert qualifier for the system unit (allows system.writeln) }
  822. if not(cs_compilesystem in current_settings.moduleswitches) and
  823. (token=_USES) then
  824. begin
  825. loadunits;
  826. { has it been compiled at a higher level ?}
  827. if current_module.state=ms_compiled then
  828. exit;
  829. end;
  830. { move the global symtable from the temporary local to global }
  831. current_module.globalsymtable:=current_module.localsymtable;
  832. current_module.localsymtable:=nil;
  833. reset_all_defs;
  834. { number all units, so we know if a unit is used by this unit or
  835. needs to be added implicitly }
  836. current_module.updatemaps;
  837. { ... parse the declarations }
  838. Message1(parser_u_parsing_interface,current_module.realmodulename^);
  839. symtablestack.push(current_module.globalsymtable);
  840. read_interface_declarations;
  841. symtablestack.pop(current_module.globalsymtable);
  842. { Export macros defined in the interface for macpas. The macros
  843. are put in the globalmacrosymtable that will only be used by other
  844. units. The current unit continues to use the localmacrosymtable }
  845. if (m_mac in current_settings.modeswitches) then
  846. begin
  847. current_module.globalmacrosymtable:=tmacrosymtable.create(true);
  848. current_module.localmacrosymtable.SymList.ForEachCall(@copy_macro,nil);
  849. end;
  850. { leave when we got an error }
  851. if (Errorcount>0) and not status.skip_error then
  852. begin
  853. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  854. status.skip_error:=true;
  855. exit;
  856. end;
  857. { Our interface is compiled, generate CRC and switch to implementation }
  858. if not(cs_compilesystem in current_settings.moduleswitches) and
  859. (Errorcount=0) then
  860. tppumodule(current_module).getppucrc;
  861. current_module.in_interface:=false;
  862. current_module.interface_compiled:=true;
  863. { First reload all units depending on our interface, we need to do this
  864. in the implementation part to prevent errorneous circular references }
  865. reload_flagged_units;
  866. { Parse the implementation section }
  867. if (m_mac in current_settings.modeswitches) and try_to_consume(_END) then
  868. has_impl:= false
  869. else
  870. has_impl:= true;
  871. parse_only:=false;
  872. { generates static symbol table }
  873. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  874. {$ifdef i386}
  875. if cs_create_pic in current_settings.moduleswitches then
  876. begin
  877. { insert symbol for got access in assembler code}
  878. gotvarsym:=tstaticvarsym.create('_GLOBAL_OFFSET_TABLE_',vs_value,voidpointertype,[vo_is_external]);
  879. gotvarsym.set_mangledname('_GLOBAL_OFFSET_TABLE_');
  880. current_module.localsymtable.insert(gotvarsym);
  881. { avoid unnecessary warnings }
  882. gotvarsym.varstate:=vs_read;
  883. gotvarsym.refs:=1;
  884. end;
  885. {$endif i386}
  886. if has_impl then
  887. begin
  888. consume(_IMPLEMENTATION);
  889. Message1(unit_u_loading_implementation_units,current_module.modulename^);
  890. { Read the implementation units }
  891. parse_implementation_uses;
  892. end;
  893. if current_module.state=ms_compiled then
  894. exit;
  895. { reset ranges/stabs in exported definitions }
  896. reset_all_defs;
  897. { All units are read, now give them a number }
  898. current_module.updatemaps;
  899. symtablestack.push(current_module.globalsymtable);
  900. symtablestack.push(current_module.localsymtable);
  901. if has_impl then
  902. begin
  903. Message1(parser_u_parsing_implementation,current_module.modulename^);
  904. if current_module.in_interface then
  905. internalerror(200212285);
  906. { Compile the unit }
  907. init_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'init'),potype_unitinit,current_module.localsymtable);
  908. init_procinfo.procdef.aliasnames.insert(make_mangledname('INIT$',current_module.localsymtable,''));
  909. init_procinfo.parse_body;
  910. { save file pos for debuginfo }
  911. current_module.mainfilepos:=init_procinfo.entrypos;
  912. end;
  913. { Generate specializations of objectdefs methods }
  914. generate_specialization_procs;
  915. { if the unit contains ansi/widestrings, initialization and
  916. finalization code must be forced }
  917. force_init_final:=tglobalsymtable(current_module.globalsymtable).needs_init_final or
  918. tstaticsymtable(current_module.localsymtable).needs_init_final;
  919. { should we force unit initialization? }
  920. { this is a hack, but how can it be done better ? }
  921. if force_init_final and ((current_module.flags and uf_init)=0) then
  922. begin
  923. { first release the not used init procinfo }
  924. if assigned(init_procinfo) then
  925. release_main_proc(init_procinfo);
  926. init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
  927. end;
  928. { finalize? }
  929. if has_impl and (token=_FINALIZATION) then
  930. begin
  931. { set module options }
  932. current_module.flags:=current_module.flags or uf_finalize;
  933. { Compile the finalize }
  934. finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
  935. finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  936. finalize_procinfo.parse_body;
  937. end
  938. else if force_init_final then
  939. finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
  940. { Now both init and finalize bodies are read and it is known
  941. which variables are used in both init and finalize we can now
  942. generate the code. This is required to prevent putting a variable in
  943. a register that is also used in the finalize body (PFV) }
  944. if assigned(init_procinfo) then
  945. begin
  946. init_procinfo.generate_code;
  947. init_procinfo.resetprocdef;
  948. release_main_proc(init_procinfo);
  949. end;
  950. if assigned(finalize_procinfo) then
  951. begin
  952. finalize_procinfo.generate_code;
  953. finalize_procinfo.resetprocdef;
  954. release_main_proc(finalize_procinfo);
  955. end;
  956. symtablestack.pop(current_module.localsymtable);
  957. symtablestack.pop(current_module.globalsymtable);
  958. { the last char should always be a point }
  959. consume(_POINT);
  960. if (Errorcount=0) then
  961. begin
  962. { tests, if all (interface) forwards are resolved }
  963. tstoredsymtable(current_module.globalsymtable).check_forwards;
  964. { check if all private fields are used }
  965. tstoredsymtable(current_module.globalsymtable).allprivatesused;
  966. { remove cross unit overloads }
  967. tstoredsymtable(current_module.globalsymtable).unchain_overloaded;
  968. { test static symtable }
  969. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  970. tstoredsymtable(current_module.localsymtable).allprivatesused;
  971. tstoredsymtable(current_module.localsymtable).check_forwards;
  972. tstoredsymtable(current_module.localsymtable).checklabels;
  973. tstoredsymtable(current_module.localsymtable).unchain_overloaded;
  974. { used units }
  975. current_module.allunitsused;
  976. end;
  977. { leave when we got an error }
  978. if (Errorcount>0) and not status.skip_error then
  979. begin
  980. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  981. status.skip_error:=true;
  982. exit;
  983. end;
  984. { do we need to add the variants unit? }
  985. maybeloadvariantsunit;
  986. { generate wrappers for interfaces }
  987. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.globalsymtable);
  988. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
  989. { generate pic helpers to load eip if necessary }
  990. gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
  991. { generate rtti/init tables }
  992. write_persistent_type_info(current_module.globalsymtable);
  993. write_persistent_type_info(current_module.localsymtable);
  994. { Tables }
  995. insertThreadVars;
  996. { Resource strings }
  997. GenerateResourceStrings;
  998. { generate debuginfo }
  999. if (cs_debuginfo in current_settings.moduleswitches) then
  1000. current_debuginfo.inserttypeinfo;
  1001. { generate imports }
  1002. if current_module.ImportLibraryList.Count>0 then
  1003. importlib.generatelib;
  1004. { insert own objectfile, or say that it's in a library
  1005. (no check for an .o when loading) }
  1006. ag:=is_assembler_generated;
  1007. if ag then
  1008. insertobjectfile
  1009. else
  1010. begin
  1011. current_module.flags:=current_module.flags or uf_no_link;
  1012. current_module.flags:=current_module.flags and not uf_has_debuginfo;
  1013. end;
  1014. if ag then
  1015. begin
  1016. { create dwarf debuginfo }
  1017. create_dwarf;
  1018. { assemble }
  1019. create_objectfile;
  1020. end;
  1021. { Write out the ppufile after the object file has been created }
  1022. store_interface_crc:=current_module.interface_crc;
  1023. {$ifdef EXTDEBUG}
  1024. store_crc:=current_module.crc;
  1025. {$endif EXTDEBUG}
  1026. if (Errorcount=0) then
  1027. tppumodule(current_module).writeppu;
  1028. if not(cs_compilesystem in current_settings.moduleswitches) then
  1029. if store_interface_crc<>current_module.interface_crc then
  1030. Message1(unit_u_interface_crc_changed,current_module.ppufilename^);
  1031. {$ifdef EXTDEBUG}
  1032. if not(cs_compilesystem in current_settings.moduleswitches) then
  1033. if (store_crc<>current_module.crc) and simplify_ppu then
  1034. Message1(unit_u_implementation_crc_changed,current_module.ppufilename^);
  1035. {$endif EXTDEBUG}
  1036. { release all overload references and local symtables that
  1037. are not needed anymore }
  1038. tstoredsymtable(current_module.localsymtable).unchain_overloaded;
  1039. tstoredsymtable(current_module.globalsymtable).unchain_overloaded;
  1040. free_localsymtables(current_module.globalsymtable);
  1041. free_localsymtables(current_module.localsymtable);
  1042. { leave when we got an error }
  1043. if (Errorcount>0) and not status.skip_error then
  1044. begin
  1045. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1046. status.skip_error:=true;
  1047. exit;
  1048. end;
  1049. Message1(unit_u_finished_compiling,current_module.modulename^);
  1050. end;
  1051. procedure insert_export(sym : TObject;arg:pointer);
  1052. var
  1053. hp : texported_item;
  1054. i : longint;
  1055. begin
  1056. case TSym(sym).typ of
  1057. { ignore: }
  1058. unitsym,
  1059. syssym,
  1060. constsym,
  1061. enumsym,
  1062. typesym:
  1063. ;
  1064. procsym:
  1065. begin
  1066. for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
  1067. begin
  1068. if not(tprocdef(tprocsym(sym).ProcdefList[i]).proccalloption in [pocall_internproc]) then
  1069. begin
  1070. hp:=texported_item.create;
  1071. // hp.sym:=tsym(sym);
  1072. hp.name:=stringdup(tprocdef(tprocsym(sym).ProcdefList[i]).mangledname);
  1073. hp.options:=hp.options or eo_name;
  1074. exportlib.exportprocedure(hp)
  1075. end;
  1076. end;
  1077. end;
  1078. staticvarsym:
  1079. begin
  1080. hp:=texported_item.create;
  1081. // hp.sym:=tsym(sym);
  1082. hp.name:=stringdup(tsym(sym).mangledname);
  1083. hp.options:=hp.options or eo_name;
  1084. exportlib.exportvar(hp);
  1085. end;
  1086. else
  1087. begin
  1088. writeln('unknown: ',ord(TSym(sym).typ));
  1089. end;
  1090. end;
  1091. end;
  1092. procedure proc_package;
  1093. var
  1094. main_file : tinputfile;
  1095. hp,hp2 : tmodule;
  1096. finalize_procinfo,
  1097. init_procinfo,
  1098. main_procinfo : tcgprocinfo;
  1099. force_init_final : boolean;
  1100. uu : tused_unit;
  1101. begin
  1102. Status.IsPackage:=true;
  1103. Status.IsExe:=true;
  1104. parse_only:=false;
  1105. main_procinfo:=nil;
  1106. init_procinfo:=nil;
  1107. finalize_procinfo:=nil;
  1108. if not RelocSectionSetExplicitly then
  1109. RelocSection:=true;
  1110. { Relocation works only without stabs under Windows when }
  1111. { external linker (LD) is used. LD generates relocs for }
  1112. { stab sections which is not loaded in memory. It causes }
  1113. { AV error when DLL is loaded and relocation is needed. }
  1114. { Internal linker does not have this problem. }
  1115. if RelocSection and
  1116. (target_info.system in system_all_windows+[system_i386_wdosx]) and
  1117. (cs_link_extern in current_settings.globalswitches) then
  1118. begin
  1119. include(current_settings.globalswitches,cs_link_strip);
  1120. { Warning stabs info does not work with reloc section !! }
  1121. if cs_debuginfo in current_settings.moduleswitches then
  1122. begin
  1123. Message1(parser_w_parser_reloc_no_debug,current_module.mainsource^);
  1124. Message(parser_w_parser_win32_debug_needs_WN);
  1125. exclude(current_settings.moduleswitches,cs_debuginfo);
  1126. end;
  1127. end;
  1128. { get correct output names }
  1129. main_file := current_scanner.inputfile;
  1130. while assigned(main_file.next) do
  1131. main_file := main_file.next;
  1132. current_module.SetFileName(main_file.path^+main_file.name^,true);
  1133. consume(_ID);
  1134. current_module.setmodulename(orgpattern);
  1135. current_module.ispackage:=true;
  1136. exportlib.preparelib(orgpattern);
  1137. if tf_library_needs_pic in target_info.flags then
  1138. include(current_settings.moduleswitches,cs_create_pic);
  1139. consume(_ID);
  1140. consume(_SEMICOLON);
  1141. { global switches are read, so further changes aren't allowed }
  1142. current_module.in_global:=false;
  1143. { setup things using the switches }
  1144. setupglobalswitches;
  1145. { set implementation flag }
  1146. current_module.in_interface:=false;
  1147. current_module.interface_compiled:=true;
  1148. { insert after the unit symbol tables the static symbol table }
  1149. { of the program }
  1150. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  1151. {Load the units used by the program we compile.}
  1152. if token=_REQUIRES then
  1153. begin
  1154. end;
  1155. {Load the units used by the program we compile.}
  1156. if (token=_ID) and (idtoken=_CONTAINS) then
  1157. begin
  1158. consume(_ID);
  1159. while true do
  1160. begin
  1161. if token=_ID then
  1162. AddUnit(pattern);
  1163. consume(_ID);
  1164. if token=_COMMA then
  1165. consume(_COMMA)
  1166. else break;
  1167. end;
  1168. consume(_SEMICOLON);
  1169. end;
  1170. { reset ranges/stabs in exported definitions }
  1171. reset_all_defs;
  1172. { All units are read, now give them a number }
  1173. current_module.updatemaps;
  1174. {Insert the name of the main program into the symbol table.}
  1175. if current_module.realmodulename^<>'' then
  1176. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  1177. Message1(parser_u_parsing_implementation,current_module.mainsource^);
  1178. symtablestack.push(current_module.localsymtable);
  1179. { should we force unit initialization? }
  1180. force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
  1181. if force_init_final then
  1182. init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
  1183. { Add symbol to the exports section for win32 so smartlinking a
  1184. DLL will include the edata section }
  1185. if assigned(exportlib) and
  1186. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  1187. ((current_module.flags and uf_has_exports)<>0) then
  1188. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',current_module.localsymtable,''),0));
  1189. { all labels must be defined before generating code }
  1190. if Errorcount=0 then
  1191. tstoredsymtable(current_module.localsymtable).checklabels;
  1192. symtablestack.pop(current_module.localsymtable);
  1193. { consume the last point }
  1194. consume(_END);
  1195. consume(_POINT);
  1196. if (Errorcount=0) then
  1197. begin
  1198. { test static symtable }
  1199. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  1200. tstoredsymtable(current_module.localsymtable).allprivatesused;
  1201. tstoredsymtable(current_module.localsymtable).check_forwards;
  1202. tstoredsymtable(current_module.localsymtable).unchain_overloaded;
  1203. current_module.allunitsused;
  1204. end;
  1205. new_section(current_asmdata.asmlists[al_globals],sec_data,'_FPCDummy',4);
  1206. current_asmdata.asmlists[al_globals].concat(tai_symbol.createname_global('_FPCDummy',AT_DATA,0));
  1207. current_asmdata.asmlists[al_globals].concat(tai_const.create_32bit(0));
  1208. new_section(current_asmdata.asmlists[al_procedures],sec_code,'',0);
  1209. current_asmdata.asmlists[al_procedures].concat(tai_symbol.createname_global('_DLLMainCRTStartup',AT_FUNCTION,0));
  1210. current_asmdata.asmlists[al_procedures].concat(tai_const.createname('_FPCDummy',0));
  1211. { leave when we got an error }
  1212. if (Errorcount>0) and not status.skip_error then
  1213. begin
  1214. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1215. status.skip_error:=true;
  1216. exit;
  1217. end;
  1218. { remove all unused units, this happends when units are removed
  1219. from the uses clause in the source and the ppu was already being loaded }
  1220. hp:=tmodule(loaded_units.first);
  1221. while assigned(hp) do
  1222. begin
  1223. hp2:=hp;
  1224. hp:=tmodule(hp.next);
  1225. if hp2.is_unit and
  1226. not assigned(hp2.globalsymtable) then
  1227. loaded_units.remove(hp2);
  1228. end;
  1229. { force exports }
  1230. uu:=tused_unit(usedunits.first);
  1231. while assigned(uu) do
  1232. begin
  1233. uu.u.globalsymtable.symlist.ForEachCall(@insert_export,nil);
  1234. uu:=tused_unit(uu.next);
  1235. end;
  1236. {$ifdef arm}
  1237. { Insert .pdata section for arm-wince.
  1238. It is needed for exception handling. }
  1239. if target_info.system in [system_arm_wince] then
  1240. InsertPData;
  1241. {$endif arm}
  1242. { generate imports }
  1243. if current_module.ImportLibraryList.Count>0 then
  1244. importlib.generatelib;
  1245. { generate debuginfo }
  1246. if (cs_debuginfo in current_settings.moduleswitches) then
  1247. current_debuginfo.inserttypeinfo;
  1248. exportlib.generatelib;
  1249. { Reference all DEBUGINFO sections from the main .fpc section }
  1250. if (cs_debuginfo in current_settings.moduleswitches) then
  1251. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  1252. { insert own objectfile }
  1253. insertobjectfile;
  1254. { assemble and link }
  1255. create_objectfile;
  1256. { We might need the symbols info if not using
  1257. the default do_extractsymbolinfo
  1258. which is a dummy function PM }
  1259. needsymbolinfo:=do_extractsymbolinfo<>@def_extractsymbolinfo;
  1260. { release all local symtables that are not needed anymore }
  1261. if (not needsymbolinfo) then
  1262. free_localsymtables(current_module.localsymtable);
  1263. { leave when we got an error }
  1264. if (Errorcount>0) and not status.skip_error then
  1265. begin
  1266. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1267. status.skip_error:=true;
  1268. exit;
  1269. end;
  1270. if (not current_module.is_unit) then
  1271. begin
  1272. { create the executable when we are at level 1 }
  1273. if (compile_level=1) then
  1274. begin
  1275. { create global resource file by collecting all resource files }
  1276. CollectResourceFiles;
  1277. { write .def file }
  1278. if (cs_link_deffile in current_settings.globalswitches) then
  1279. deffile.writefile;
  1280. { insert all .o files from all loaded units and
  1281. unload the units, we don't need them anymore.
  1282. Keep the current_module because that is still needed }
  1283. hp:=tmodule(loaded_units.first);
  1284. while assigned(hp) do
  1285. begin
  1286. { the package itself contains no code so far }
  1287. linker.AddModuleFiles(hp);
  1288. hp2:=tmodule(hp.next);
  1289. if (hp<>current_module) and
  1290. (not needsymbolinfo) then
  1291. begin
  1292. loaded_units.remove(hp);
  1293. hp.free;
  1294. end;
  1295. hp:=hp2;
  1296. end;
  1297. linker.MakeSharedLibrary
  1298. end;
  1299. { Give Fatal with error count for linker errors }
  1300. if (Errorcount>0) and not status.skip_error then
  1301. begin
  1302. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1303. status.skip_error:=true;
  1304. end;
  1305. end;
  1306. end;
  1307. procedure proc_program(islibrary : boolean);
  1308. var
  1309. main_file : tinputfile;
  1310. hp,hp2 : tmodule;
  1311. finalize_procinfo,
  1312. init_procinfo,
  1313. main_procinfo : tcgprocinfo;
  1314. force_init_final : boolean;
  1315. begin
  1316. DLLsource:=islibrary;
  1317. Status.IsLibrary:=IsLibrary;
  1318. Status.IsPackage:=false;
  1319. Status.IsExe:=true;
  1320. parse_only:=false;
  1321. main_procinfo:=nil;
  1322. init_procinfo:=nil;
  1323. finalize_procinfo:=nil;
  1324. { DLL defaults to create reloc info }
  1325. if islibrary then
  1326. begin
  1327. if not RelocSectionSetExplicitly then
  1328. RelocSection:=true;
  1329. end;
  1330. { Relocation works only without stabs under Windows when }
  1331. { external linker (LD) is used. LD generates relocs for }
  1332. { stab sections which is not loaded in memory. It causes }
  1333. { AV error when DLL is loaded and relocation is needed. }
  1334. { Internal linker does not have this problem. }
  1335. if RelocSection and
  1336. (target_info.system in system_all_windows+[system_i386_wdosx]) and
  1337. (cs_link_extern in current_settings.globalswitches) then
  1338. begin
  1339. include(current_settings.globalswitches,cs_link_strip);
  1340. { Warning stabs info does not work with reloc section !! }
  1341. if cs_debuginfo in current_settings.moduleswitches then
  1342. begin
  1343. Message1(parser_w_parser_reloc_no_debug,current_module.mainsource^);
  1344. Message(parser_w_parser_win32_debug_needs_WN);
  1345. exclude(current_settings.moduleswitches,cs_debuginfo);
  1346. end;
  1347. end;
  1348. { get correct output names }
  1349. main_file := current_scanner.inputfile;
  1350. while assigned(main_file.next) do
  1351. main_file := main_file.next;
  1352. current_module.SetFileName(main_file.path^+main_file.name^,true);
  1353. if islibrary then
  1354. begin
  1355. consume(_LIBRARY);
  1356. current_module.setmodulename(orgpattern);
  1357. current_module.islibrary:=true;
  1358. exportlib.preparelib(orgpattern);
  1359. if tf_library_needs_pic in target_info.flags then
  1360. include(current_settings.moduleswitches,cs_create_pic);
  1361. consume(_ID);
  1362. consume(_SEMICOLON);
  1363. end
  1364. else
  1365. { is there an program head ? }
  1366. if token=_PROGRAM then
  1367. begin
  1368. consume(_PROGRAM);
  1369. current_module.setmodulename(orgpattern);
  1370. if (target_info.system in system_unit_program_exports) then
  1371. exportlib.preparelib(orgpattern);
  1372. consume(_ID);
  1373. if token=_LKLAMMER then
  1374. begin
  1375. consume(_LKLAMMER);
  1376. repeat
  1377. consume(_ID);
  1378. until not try_to_consume(_COMMA);
  1379. consume(_RKLAMMER);
  1380. end;
  1381. consume(_SEMICOLON);
  1382. end
  1383. else if (target_info.system in system_unit_program_exports) then
  1384. exportlib.preparelib(current_module.realmodulename^);
  1385. { global switches are read, so further changes aren't allowed }
  1386. current_module.in_global:=false;
  1387. { setup things using the switches }
  1388. setupglobalswitches;
  1389. { set implementation flag }
  1390. current_module.in_interface:=false;
  1391. current_module.interface_compiled:=true;
  1392. { insert after the unit symbol tables the static symbol table }
  1393. { of the program }
  1394. current_module.localsymtable:=tstaticsymtable.create(current_module.modulename^,current_module.moduleid);
  1395. { load standard units (system,objpas,profile unit) }
  1396. loaddefaultunits;
  1397. { Load units provided on the command line }
  1398. loadautounits;
  1399. {Load the units used by the program we compile.}
  1400. if token=_USES then
  1401. loadunits;
  1402. { reset ranges/stabs in exported definitions }
  1403. reset_all_defs;
  1404. { All units are read, now give them a number }
  1405. current_module.updatemaps;
  1406. {Insert the name of the main program into the symbol table.}
  1407. if current_module.realmodulename^<>'' then
  1408. current_module.localsymtable.insert(tunitsym.create(current_module.realmodulename^,current_module));
  1409. Message1(parser_u_parsing_implementation,current_module.mainsource^);
  1410. symtablestack.push(current_module.localsymtable);
  1411. { The program intialization needs an alias, so it can be called
  1412. from the bootstrap code.}
  1413. if islibrary then
  1414. begin
  1415. main_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
  1416. { Win32 startup code needs a single name }
  1417. if not(target_info.system in systems_darwin) then
  1418. main_procinfo.procdef.aliasnames.insert('PASCALMAIN')
  1419. else
  1420. main_procinfo.procdef.aliasnames.insert(target_info.Cprefix+'PASCALMAIN')
  1421. end
  1422. else if (target_info.system in ([system_i386_netware,system_i386_netwlibc,system_powerpc_macos]+systems_darwin)) then
  1423. begin
  1424. main_procinfo:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
  1425. end
  1426. else
  1427. begin
  1428. main_procinfo:=create_main_proc(mainaliasname,potype_proginit,current_module.localsymtable);
  1429. main_procinfo.procdef.aliasnames.insert('PASCALMAIN');
  1430. end;
  1431. main_procinfo.parse_body;
  1432. { save file pos for debuginfo }
  1433. current_module.mainfilepos:=main_procinfo.entrypos;
  1434. { Generate specializations of objectdefs methods }
  1435. generate_specialization_procs;
  1436. { should we force unit initialization? }
  1437. force_init_final:=tstaticsymtable(current_module.localsymtable).needs_init_final;
  1438. if force_init_final then
  1439. init_procinfo:=gen_implicit_initfinal(uf_init,current_module.localsymtable);
  1440. { Add symbol to the exports section for win32 so smartlinking a
  1441. DLL will include the edata section }
  1442. if assigned(exportlib) and
  1443. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  1444. ((current_module.flags and uf_has_exports)<>0) then
  1445. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',current_module.localsymtable,''),0));
  1446. { finalize? }
  1447. if token=_FINALIZATION then
  1448. begin
  1449. { set module options }
  1450. current_module.flags:=current_module.flags or uf_finalize;
  1451. { Parse the finalize }
  1452. finalize_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,'finalize'),potype_unitfinalize,current_module.localsymtable);
  1453. finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',current_module.localsymtable,''));
  1454. finalize_procinfo.procdef.aliasnames.insert('PASCALFINALIZE');
  1455. finalize_procinfo.parse_body;
  1456. end
  1457. else
  1458. if force_init_final then
  1459. finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
  1460. { all labels must be defined before generating code }
  1461. if Errorcount=0 then
  1462. tstoredsymtable(current_module.localsymtable).checklabels;
  1463. { See remark in unit init/final }
  1464. main_procinfo.generate_code;
  1465. main_procinfo.resetprocdef;
  1466. release_main_proc(main_procinfo);
  1467. if assigned(init_procinfo) then
  1468. begin
  1469. init_procinfo.generate_code;
  1470. init_procinfo.resetprocdef;
  1471. release_main_proc(init_procinfo);
  1472. end;
  1473. if assigned(finalize_procinfo) then
  1474. begin
  1475. finalize_procinfo.generate_code;
  1476. finalize_procinfo.resetprocdef;
  1477. release_main_proc(finalize_procinfo);
  1478. end;
  1479. symtablestack.pop(current_module.localsymtable);
  1480. { consume the last point }
  1481. consume(_POINT);
  1482. if (Errorcount=0) then
  1483. begin
  1484. { test static symtable }
  1485. tstoredsymtable(current_module.localsymtable).allsymbolsused;
  1486. tstoredsymtable(current_module.localsymtable).allprivatesused;
  1487. tstoredsymtable(current_module.localsymtable).check_forwards;
  1488. tstoredsymtable(current_module.localsymtable).unchain_overloaded;
  1489. current_module.allunitsused;
  1490. end;
  1491. { leave when we got an error }
  1492. if (Errorcount>0) and not status.skip_error then
  1493. begin
  1494. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1495. status.skip_error:=true;
  1496. exit;
  1497. end;
  1498. { remove all unused units, this happends when units are removed
  1499. from the uses clause in the source and the ppu was already being loaded }
  1500. hp:=tmodule(loaded_units.first);
  1501. while assigned(hp) do
  1502. begin
  1503. hp2:=hp;
  1504. hp:=tmodule(hp.next);
  1505. if hp2.is_unit and
  1506. not assigned(hp2.globalsymtable) then
  1507. loaded_units.remove(hp2);
  1508. end;
  1509. { do we need to add the variants unit? }
  1510. maybeloadvariantsunit;
  1511. linker.initsysinitunitname;
  1512. if target_info.system in system_internal_sysinit then
  1513. begin
  1514. { add start/halt unit }
  1515. AddUnit(linker.sysinitunit);
  1516. end;
  1517. {$ifdef arm}
  1518. { Insert .pdata section for arm-wince.
  1519. It is needed for exception handling. }
  1520. if target_info.system in [system_arm_wince] then
  1521. InsertPData;
  1522. {$endif arm}
  1523. InsertThreadvars;
  1524. { generate pic helpers to load eip if necessary }
  1525. gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
  1526. { generate rtti/init tables }
  1527. write_persistent_type_info(current_module.localsymtable);
  1528. { generate wrappers for interfaces }
  1529. gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
  1530. { generate imports }
  1531. if current_module.ImportLibraryList.Count>0 then
  1532. importlib.generatelib;
  1533. { generate debuginfo }
  1534. if (cs_debuginfo in current_settings.moduleswitches) then
  1535. current_debuginfo.inserttypeinfo;
  1536. if islibrary or (target_info.system in system_unit_program_exports) then
  1537. exportlib.generatelib;
  1538. { Reference all DEBUGINFO sections from the main .fpc section }
  1539. if (cs_debuginfo in current_settings.moduleswitches) then
  1540. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  1541. { Resource strings }
  1542. GenerateResourceStrings;
  1543. { insert Tables and StackLength }
  1544. insertinitfinaltable;
  1545. InsertThreadvarTablesTable;
  1546. InsertResourceTablesTable;
  1547. insertmemorysizes;
  1548. { Insert symbol to resource info }
  1549. InsertResourceInfo;
  1550. { create dwarf debuginfo }
  1551. create_dwarf;
  1552. { insert own objectfile }
  1553. insertobjectfile;
  1554. { assemble and link }
  1555. create_objectfile;
  1556. { We might need the symbols info if not using
  1557. the default do_extractsymbolinfo
  1558. which is a dummy function PM }
  1559. needsymbolinfo:=do_extractsymbolinfo<>@def_extractsymbolinfo;
  1560. { release all local symtables that are not needed anymore }
  1561. if (not needsymbolinfo) then
  1562. free_localsymtables(current_module.localsymtable);
  1563. { leave when we got an error }
  1564. if (Errorcount>0) and not status.skip_error then
  1565. begin
  1566. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1567. status.skip_error:=true;
  1568. exit;
  1569. end;
  1570. if (not current_module.is_unit) then
  1571. begin
  1572. { create the executable when we are at level 1 }
  1573. if (compile_level=1) then
  1574. begin
  1575. { create global resource file by collecting all resource files }
  1576. CollectResourceFiles;
  1577. { write .def file }
  1578. if (cs_link_deffile in current_settings.globalswitches) then
  1579. deffile.writefile;
  1580. { insert all .o files from all loaded units and
  1581. unload the units, we don't need them anymore.
  1582. Keep the current_module because that is still needed }
  1583. hp:=tmodule(loaded_units.first);
  1584. while assigned(hp) do
  1585. begin
  1586. linker.AddModuleFiles(hp);
  1587. hp2:=tmodule(hp.next);
  1588. if (hp<>current_module) and
  1589. (not needsymbolinfo) then
  1590. begin
  1591. loaded_units.remove(hp);
  1592. hp.free;
  1593. end;
  1594. hp:=hp2;
  1595. end;
  1596. { finally we can create a executable }
  1597. if DLLSource then
  1598. linker.MakeSharedLibrary
  1599. else
  1600. linker.MakeExecutable;
  1601. end;
  1602. { Give Fatal with error count for linker errors }
  1603. if (Errorcount>0) and not status.skip_error then
  1604. begin
  1605. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1606. status.skip_error:=true;
  1607. end;
  1608. end;
  1609. end;
  1610. end.