pmodules.pas 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. Handles the parsing and loading of the modules (ppufiles)
  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 pmodules;
  19. {$i defines.inc}
  20. {$define New_GDB}
  21. interface
  22. procedure proc_unit;
  23. procedure proc_program(islibrary : boolean);
  24. implementation
  25. uses
  26. globtype,version,systems,tokens,
  27. cutils,comphook,
  28. globals,verbose,fmodule,finput,fppu,
  29. symconst,symbase,symppu,symdef,symsym,symtable,aasm,
  30. {$ifdef newcg}
  31. cgbase,
  32. {$else newcg}
  33. hcodegen,
  34. {$ifdef i386}
  35. cgai386,
  36. {$endif i386}
  37. {$endif newcg}
  38. link,assemble,import,export,gendef,ppu,comprsrc,
  39. cresstr,cpubase,cpuasm,
  40. {$ifdef GDB}
  41. gdb,
  42. {$endif GDB}
  43. scanner,pbase,pexpr,psystem,psub,parser;
  44. procedure create_objectfile;
  45. var
  46. DLLScanner : TDLLScanner;
  47. s : string;
  48. begin
  49. { try to create import entries from system dlls }
  50. if target_info.DllScanSupported and
  51. (not current_module.linkOtherSharedLibs.Empty) then
  52. begin
  53. { Init DLLScanner }
  54. if assigned(CDLLScanner[target_info.target]) then
  55. DLLScanner:=CDLLScanner[target_info.target].Create
  56. else
  57. internalerror(200104121);
  58. { Walk all shared libs }
  59. While not current_module.linkOtherSharedLibs.Empty do
  60. begin
  61. S:=current_module.linkOtherSharedLibs.Getusemask(link_allways);
  62. DLLScanner.scan(s)
  63. end;
  64. DLLscanner.Free;
  65. { Recreate import section }
  66. if (target_info.target=target_i386_win32) then
  67. begin
  68. if assigned(importssection)then
  69. importssection.clear
  70. else
  71. importssection:=taasmoutput.Create;
  72. importlib.generatelib;
  73. end;
  74. end;
  75. { create the .s file and assemble it }
  76. GenerateAsm(false);
  77. { Also create a smartlinked version ? }
  78. if (cs_create_smart in aktmoduleswitches) then
  79. begin
  80. { regenerate the importssection for win32 }
  81. if assigned(importssection) and
  82. (target_info.target=target_i386_win32) then
  83. begin
  84. importsSection.clear;
  85. importlib.generatesmartlib;
  86. end;
  87. GenerateAsm(true);
  88. if target_asm.needar then
  89. Linker.MakeStaticLibrary;
  90. end;
  91. { resource files }
  92. CompileResourceFiles;
  93. end;
  94. procedure insertobjectfile;
  95. { Insert the used object file for this unit in the used list for this unit }
  96. begin
  97. current_module.linkunitofiles.add(current_module.objfilename^,link_static);
  98. current_module.flags:=current_module.flags or uf_static_linked;
  99. if (cs_create_smart in aktmoduleswitches) then
  100. begin
  101. current_module.linkunitstaticlibs.add(current_module.staticlibfilename^,link_smart);
  102. current_module.flags:=current_module.flags or uf_smart_linked;
  103. end;
  104. end;
  105. procedure insertsegment;
  106. procedure fixseg(p:TAAsmoutput;sec:tsection);
  107. begin
  108. p.insert(Tai_section.Create(sec));
  109. if (cs_create_smart in aktmoduleswitches) then
  110. p.insert(Tai_cut.Create);
  111. p.concat(Tai_section.Create(sec_none));
  112. end;
  113. begin
  114. { Insert Ident of the compiler }
  115. if (not (cs_create_smart in aktmoduleswitches))
  116. {$ifndef EXTDEBUG}
  117. and (not current_module.is_unit)
  118. {$endif}
  119. then
  120. begin
  121. dataSegment.insert(Tai_align.Create(4));
  122. dataSegment.insert(Tai_string.Create('FPC '+full_version_string+
  123. ' ['+date_string+'] for '+target_cpu_string+' - '+target_info.shortname));
  124. end;
  125. { finish codesegment }
  126. {$ifdef i386}
  127. codeSegment.concat(Tai_align.Create(16));
  128. {$else}
  129. if cs_littlesize in aktglobalswitches then
  130. codesegment.concat(tai_align.create(2))
  131. else
  132. codesegment.concat(tai_align.create(4));
  133. {$endif}
  134. { Insert start and end of sections }
  135. fixseg(codesegment,sec_code);
  136. fixseg(datasegment,sec_data);
  137. fixseg(bsssegment,sec_bss);
  138. { we should use .rdata section for these two no ? }
  139. { .rdata is a read only data section (PM) }
  140. fixseg(rttilist,sec_data);
  141. fixseg(consts,sec_data);
  142. if assigned(resourcestringlist) then
  143. fixseg(resourcestringlist,sec_data);
  144. {$ifdef GDB}
  145. if assigned(debuglist) then
  146. begin
  147. debugList.insert(Tai_symbol.Createname('gcc2_compiled',0));
  148. debugList.insert(Tai_symbol.Createname('fpc_compiled',0));
  149. fixseg(debuglist,sec_code);
  150. end;
  151. {$endif GDB}
  152. end;
  153. Procedure InsertResourceTablesTable;
  154. var
  155. hp : tused_unit;
  156. ResourceStringTables : taasmoutput;
  157. count : longint;
  158. begin
  159. ResourceStringTables:=TAAsmOutput.Create;
  160. count:=0;
  161. hp:=tused_unit(usedunits.first);
  162. while assigned(hp) do
  163. begin
  164. If (hp.u.flags and uf_has_resources)=uf_has_resources then
  165. begin
  166. ResourceStringTables.concat(Tai_const_symbol.Createname(hp.u.modulename^+'_RESOURCESTRINGLIST'));
  167. inc(count);
  168. end;
  169. hp:=tused_unit(hp.next);
  170. end;
  171. { Add program resources, if any }
  172. If ResourceStringList<>Nil then
  173. begin
  174. ResourceStringTables.concat(Tai_const_symbol.Createname(current_module.modulename^+'_RESOURCESTRINGLIST'));
  175. Inc(Count);
  176. end;
  177. { TableCount }
  178. ResourceStringTables.insert(Tai_const.Create_32bit(count));
  179. ResourceStringTables.insert(Tai_symbol.Createdataname_global('FPC_RESOURCESTRINGTABLES',0));
  180. ResourceStringTables.concat(Tai_symbol_end.Createname('FPC_RESOURCESTRINGTABLES'));
  181. { insert in data segment }
  182. if (cs_create_smart in aktmoduleswitches) then
  183. dataSegment.concat(Tai_cut.Create);
  184. dataSegment.concatlist(ResourceStringTables);
  185. ResourceStringTables.free;
  186. end;
  187. procedure InsertInitFinalTable;
  188. var
  189. hp : tused_unit;
  190. unitinits : taasmoutput;
  191. count : longint;
  192. begin
  193. unitinits:=TAAsmOutput.Create;
  194. count:=0;
  195. hp:=tused_unit(usedunits.first);
  196. while assigned(hp) do
  197. begin
  198. { call the unit init code and make it external }
  199. if (hp.u.flags and (uf_init or uf_finalize))<>0 then
  200. begin
  201. if (hp.u.flags and uf_init)<>0 then
  202. unitinits.concat(Tai_const_symbol.Createname('INIT$$'+hp.u.modulename^))
  203. else
  204. unitinits.concat(Tai_const.Create_32bit(0));
  205. if (hp.u.flags and uf_finalize)<>0 then
  206. unitinits.concat(Tai_const_symbol.Createname('FINALIZE$$'+hp.u.modulename^))
  207. else
  208. unitinits.concat(Tai_const.Create_32bit(0));
  209. inc(count);
  210. end;
  211. hp:=tused_unit(hp.next);
  212. end;
  213. if current_module.islibrary then
  214. if (current_module.flags and uf_finalize)<>0 then
  215. begin
  216. { INIT code is done by PASCALMAIN calling }
  217. unitinits.concat(Tai_const.Create_32bit(0));
  218. unitinits.concat(Tai_const_symbol.Createname('FINALIZE$$'+current_module.modulename^));
  219. inc(count);
  220. end;
  221. { TableCount,InitCount }
  222. unitinits.insert(Tai_const.Create_32bit(0));
  223. unitinits.insert(Tai_const.Create_32bit(count));
  224. unitinits.insert(Tai_symbol.Createdataname_global('INITFINAL',0));
  225. unitinits.concat(Tai_symbol_end.Createname('INITFINAL'));
  226. { insert in data segment }
  227. if (cs_create_smart in aktmoduleswitches) then
  228. dataSegment.concat(Tai_cut.Create);
  229. dataSegment.concatlist(unitinits);
  230. unitinits.free;
  231. end;
  232. procedure insertheap;
  233. begin
  234. if (cs_create_smart in aktmoduleswitches) then
  235. begin
  236. bssSegment.concat(Tai_cut.Create);
  237. dataSegment.concat(Tai_cut.Create);
  238. end;
  239. { On the Macintosh Classic M68k Architecture
  240. The Heap variable is simply a POINTER to the
  241. real HEAP. The HEAP must be set up by the RTL
  242. and must store the pointer in this value.
  243. On OS/2 the heap is also intialized by the RTL. We do
  244. not output a pointer }
  245. case target_info.target of
  246. {$ifdef i386}
  247. target_i386_OS2:
  248. ;
  249. {$endif i386}
  250. {$ifdef alpha}
  251. target_alpha_linux:
  252. ;
  253. {$endif alpha}
  254. {$ifdef powerpc}
  255. target_powerpc_linux:
  256. ;
  257. {$endif powerpc}
  258. {$ifdef m68k}
  259. target_m68k_Mac:
  260. bssSegment.concat(Tai_datablock.Create_global('HEAP',4));
  261. target_m68k_PalmOS:
  262. ;
  263. {$endif m68k}
  264. else
  265. bssSegment.concat(Tai_datablock.Create_global('HEAP',heapsize));
  266. end;
  267. {$ifdef m68k}
  268. if target_info.target<>target_m68k_PalmOS then
  269. begin
  270. dataSegment.concat(Tai_symbol.Createdataname_global('HEAPSIZE',4));
  271. dataSegment.concat(Tai_const.Create_32bit(heapsize));
  272. end;
  273. {$else m68k}
  274. dataSegment.concat(Tai_symbol.Createdataname_global('HEAPSIZE',4));
  275. dataSegment.concat(Tai_const.Create_32bit(heapsize));
  276. {$endif m68k}
  277. end;
  278. procedure inserttargetspecific;
  279. begin
  280. case target_info.target of
  281. {$ifdef alpha}
  282. target_alpha_linux:
  283. ;
  284. {$endif alpha}
  285. {$ifdef powerpc}
  286. target_powerpc_linux:
  287. ;
  288. {$endif powerpc}
  289. {$ifdef i386}
  290. target_i386_GO32V2 :
  291. begin
  292. { stacksize can be specified }
  293. dataSegment.concat(Tai_symbol.Createdataname_global('__stklen',4));
  294. dataSegment.concat(Tai_const.Create_32bit(stacksize));
  295. end;
  296. {$endif i386}
  297. {$ifdef m68k}
  298. target_m68k_Atari :
  299. begin
  300. { stacksize can be specified }
  301. dataSegment.concat(Tai_symbol.Createdataname_global('__stklen',4));
  302. dataSegment.concat(Tai_const.Create_32bit(stacksize));
  303. end;
  304. {$endif m68k}
  305. end;
  306. end;
  307. procedure loaddefaultunits;
  308. var
  309. hp : tmodule;
  310. unitsym : tunitsym;
  311. begin
  312. { are we compiling the system unit? }
  313. if (cs_compilesystem in aktmoduleswitches) then
  314. begin
  315. { create system defines }
  316. createconstdefs;
  317. { we don't need to reset anything, it's already done in parser.pas }
  318. exit;
  319. end;
  320. { insert the system unit, it is allways the first }
  321. hp:=loadunit('System','');
  322. systemunit:=tglobalsymtable(hp.globalsymtable);
  323. { it's always the first unit }
  324. systemunit.next:=nil;
  325. symtablestack:=systemunit;
  326. { add to the used units }
  327. current_module.used_units.concat(tused_unit.create(hp,true));
  328. unitsym:=tunitsym.create('System',systemunit);
  329. inc(unitsym.refs);
  330. refsymtable.insert(unitsym);
  331. { read default constant definitions }
  332. make_ref:=false;
  333. readconstdefs;
  334. make_ref:=true;
  335. { Objpas unit? }
  336. if m_objpas in aktmodeswitches then
  337. begin
  338. hp:=loadunit('ObjPas','');
  339. tsymtable(hp.globalsymtable).next:=symtablestack;
  340. symtablestack:=hp.globalsymtable;
  341. { add to the used units }
  342. current_module.used_units.concat(tused_unit.create(hp,true));
  343. unitsym:=tunitsym.create('ObjPas',hp.globalsymtable);
  344. inc(unitsym.refs);
  345. refsymtable.insert(unitsym);
  346. end;
  347. { Profile unit? Needed for go32v2 only }
  348. if (cs_profile in aktmoduleswitches) and (target_info.target=target_i386_go32v2) then
  349. begin
  350. hp:=loadunit('Profile','');
  351. tsymtable(hp.globalsymtable).next:=symtablestack;
  352. symtablestack:=hp.globalsymtable;
  353. { add to the used units }
  354. current_module.used_units.concat(tused_unit.create(hp,true));
  355. unitsym:=tunitsym.create('Profile',hp.globalsymtable);
  356. inc(unitsym.refs);
  357. refsymtable.insert(unitsym);
  358. end;
  359. { Units only required for main module }
  360. if not(current_module.is_unit) then
  361. begin
  362. { Heaptrc unit }
  363. if (cs_gdb_heaptrc in aktglobalswitches) then
  364. begin
  365. hp:=loadunit('HeapTrc','');
  366. tsymtable(hp.globalsymtable).next:=symtablestack;
  367. symtablestack:=hp.globalsymtable;
  368. { add to the used units }
  369. current_module.used_units.concat(tused_unit.create(hp,true));
  370. unitsym:=tunitsym.create('HeapTrc',hp.globalsymtable);
  371. inc(unitsym.refs);
  372. refsymtable.insert(unitsym);
  373. end;
  374. { Lineinfo unit }
  375. if (cs_gdb_lineinfo in aktglobalswitches) then
  376. begin
  377. hp:=loadunit('LineInfo','');
  378. tsymtable(hp.globalsymtable).next:=symtablestack;
  379. symtablestack:=hp.globalsymtable;
  380. { add to the used units }
  381. current_module.used_units.concat(tused_unit.create(hp,true));
  382. unitsym:=tunitsym.create('LineInfo',hp.globalsymtable);
  383. inc(unitsym.refs);
  384. refsymtable.insert(unitsym);
  385. end;
  386. end;
  387. { save default symtablestack }
  388. defaultsymtablestack:=symtablestack;
  389. end;
  390. procedure loadunits;
  391. var
  392. s,sorg : stringid;
  393. fn : string;
  394. pu,
  395. hp : tused_unit;
  396. hp2 : tmodule;
  397. hp3 : tsymtable;
  398. oldprocsym:tprocsym;
  399. unitsym : tunitsym;
  400. begin
  401. oldprocsym:=aktprocsym;
  402. consume(_USES);
  403. {$ifdef DEBUG}
  404. test_symtablestack;
  405. {$endif DEBUG}
  406. repeat
  407. s:=pattern;
  408. sorg:=orgpattern;
  409. consume(_ID);
  410. { support "<unit> in '<file>'" construct, but not for tp7 }
  411. if not(m_tp7 in aktmodeswitches) then
  412. begin
  413. if try_to_consume(_OP_IN) then
  414. fn:=get_stringconst
  415. else
  416. fn:='';
  417. end;
  418. { Give a warning if objpas is loaded }
  419. if s='OBJPAS' then
  420. Message(parser_w_no_objpas_use_mode);
  421. { check if the unit is already used }
  422. pu:=tused_unit(current_module.used_units.first);
  423. while assigned(pu) do
  424. begin
  425. if (pu.name^=s) then
  426. break;
  427. pu:=tused_unit(pu.next);
  428. end;
  429. { avoid uses of itself }
  430. if not assigned(pu) and (s<>current_module.modulename^) then
  431. begin
  432. { load the unit }
  433. hp2:=loadunit(sorg,fn);
  434. { the current module uses the unit hp2 }
  435. current_module.used_units.concat(tused_unit.create(hp2,not current_module.in_implementation));
  436. tused_unit(current_module.used_units.last).in_uses:=true;
  437. if current_module.compiled then
  438. exit;
  439. unitsym:=tunitsym.create(sorg,hp2.globalsymtable);
  440. { never claim about unused unit if
  441. there is init or finalize code PM }
  442. if (hp2.flags and (uf_init or uf_finalize))<>0 then
  443. inc(unitsym.refs);
  444. refsymtable.insert(unitsym);
  445. end
  446. else
  447. Message1(sym_e_duplicate_id,s);
  448. if token=_COMMA then
  449. begin
  450. pattern:='';
  451. consume(_COMMA);
  452. end
  453. else
  454. break;
  455. until false;
  456. consume(_SEMICOLON);
  457. { set the symtable to systemunit so it gets reorderd correctly }
  458. symtablestack:=defaultsymtablestack;
  459. { now insert the units in the symtablestack }
  460. hp:=tused_unit(current_module.used_units.first);
  461. while assigned(hp) do
  462. begin
  463. {$IfDef GDB}
  464. if (cs_debuginfo in aktmoduleswitches) and
  465. (cs_gdb_dbx in aktglobalswitches) and
  466. not hp.is_stab_written then
  467. begin
  468. tglobalsymtable(hp.u.globalsymtable).concattypestabto(debuglist);
  469. hp.is_stab_written:=true;
  470. hp.unitid:=tsymtable(hp.u.globalsymtable).unitid;
  471. end;
  472. {$EndIf GDB}
  473. if hp.in_uses then
  474. begin
  475. hp3:=symtablestack;
  476. while assigned(hp3) do
  477. begin
  478. { insert units only once ! }
  479. if hp.u.globalsymtable=hp3 then
  480. break;
  481. hp3:=hp3.next;
  482. { unit isn't inserted }
  483. if hp3=nil then
  484. begin
  485. tsymtable(hp.u.globalsymtable).next:=symtablestack;
  486. symtablestack:=tsymtable(hp.u.globalsymtable);
  487. {$ifdef CHAINPROCSYMS}
  488. symtablestack.chainprocsyms;
  489. {$endif CHAINPROCSYMS}
  490. {$ifdef DEBUG}
  491. test_symtablestack;
  492. {$endif DEBUG}
  493. end;
  494. end;
  495. end;
  496. hp:=tused_unit(hp.next);
  497. end;
  498. aktprocsym:=oldprocsym;
  499. end;
  500. procedure write_gdb_info;
  501. {$IfDef GDB}
  502. var
  503. hp : tused_unit;
  504. begin
  505. if not (cs_debuginfo in aktmoduleswitches) then
  506. exit;
  507. if (cs_gdb_dbx in aktglobalswitches) then
  508. begin
  509. debugList.concat(Tai_asm_comment.Create(strpnew('EINCL of global '+
  510. tglobalsymtable(current_module.globalsymtable).name^+' has index '+
  511. tostr(tglobalsymtable(current_module.globalsymtable).unitid))));
  512. debugList.concat(Tai_stabs.Create(strpnew('"'+
  513. tglobalsymtable(current_module.globalsymtable).name^+'",'+
  514. tostr(N_EINCL)+',0,0,0')));
  515. tglobalsymtable(current_module.globalsymtable).dbx_count_ok:={true}false;
  516. dbx_counter:=tglobalsymtable(current_module.globalsymtable).prev_dbx_counter;
  517. do_count_dbx:=false;
  518. end;
  519. { now insert the units in the symtablestack }
  520. hp:=tused_unit(current_module.used_units.first);
  521. while assigned(hp) do
  522. begin
  523. if (cs_debuginfo in aktmoduleswitches) and
  524. not hp.is_stab_written then
  525. begin
  526. tglobalsymtable(hp.u.globalsymtable).concattypestabto(debuglist);
  527. hp.is_stab_written:=true;
  528. hp.unitid:=tsymtable(hp.u.globalsymtable).unitid;
  529. end;
  530. hp:=tused_unit(hp.next);
  531. end;
  532. if current_module.in_implementation and
  533. assigned(current_module.localsymtable) then
  534. begin
  535. { all types }
  536. tstaticsymtable(current_module.localsymtable).concattypestabto(debuglist);
  537. { and all local symbols}
  538. tstaticsymtable(current_module.localsymtable).concatstabto(debuglist);
  539. end
  540. else if assigned(current_module.globalsymtable) then
  541. begin
  542. { all types }
  543. tglobalsymtable(current_module.globalsymtable).concattypestabto(debuglist);
  544. { and all local symbols}
  545. tglobalsymtable(current_module.globalsymtable).concatstabto(debuglist);
  546. end;
  547. end;
  548. {$Else GDB}
  549. begin
  550. end;
  551. {$EndIf GDB}
  552. procedure parse_implementation_uses(symt:tsymtable);
  553. begin
  554. if token=_USES then
  555. begin
  556. loadunits;
  557. {$ifdef DEBUG}
  558. test_symtablestack;
  559. {$endif DEBUG}
  560. end;
  561. end;
  562. procedure setupglobalswitches;
  563. begin
  564. { can't have local browser when no global browser }
  565. if (cs_local_browser in aktmoduleswitches) and
  566. not(cs_browser in aktmoduleswitches) then
  567. exclude(aktmoduleswitches,cs_local_browser);
  568. { define a symbol in delphi,objfpc,tp,gpc mode }
  569. if (m_delphi in aktmodeswitches) then
  570. current_scanner.def_macro('FPC_DELPHI')
  571. else
  572. if (m_tp in aktmodeswitches) then
  573. current_scanner.def_macro('FPC_TP')
  574. else
  575. if (m_objfpc in aktmodeswitches) then
  576. current_scanner.def_macro('FPC_OBJFPC')
  577. else
  578. if (m_gpc in aktmodeswitches) then
  579. current_scanner.def_macro('FPC_GPC');
  580. end;
  581. procedure gen_main_procsym(const name:string;options:tproctypeoption;st:tsymtable);
  582. var
  583. stt : tsymtable;
  584. begin
  585. {Generate a procsym for main}
  586. make_ref:=false;
  587. aktprocsym:=tprocsym.create('$'+name);
  588. { main are allways used }
  589. inc(aktprocsym.refs);
  590. {Try to insert in in static symtable ! }
  591. stt:=symtablestack;
  592. symtablestack:=st;
  593. aktprocsym.definition:=tprocdef.create;
  594. symtablestack:=stt;
  595. aktprocsym.definition.proctypeoption:=options;
  596. aktprocsym.definition.setmangledname(target_info.cprefix+name);
  597. aktprocsym.definition.forwarddef:=false;
  598. make_ref:=true;
  599. { The localst is a local symtable. Change it into the static
  600. symtable }
  601. aktprocsym.definition.localst.free;
  602. aktprocsym.definition.localst:=st;
  603. { and insert the procsym in symtable }
  604. st.insert(aktprocsym);
  605. { set some informations about the main program }
  606. with procinfo^ do
  607. begin
  608. returntype:=voidtype;
  609. _class:=nil;
  610. para_offset:=8;
  611. framepointer:=frame_pointer;
  612. flags:=0;
  613. end;
  614. end;
  615. procedure proc_unit;
  616. function is_assembler_generated:boolean;
  617. begin
  618. is_assembler_generated:=(Errorcount=0) and
  619. not(
  620. codeSegment.empty and
  621. dataSegment.empty and
  622. bssSegment.empty and
  623. ((importssection=nil) or importsSection.empty) and
  624. ((resourcesection=nil) or resourceSection.empty) and
  625. ((resourcestringlist=nil) or resourcestringList.empty)
  626. );
  627. end;
  628. var
  629. main_file: tinputfile;
  630. st : tsymtable;
  631. unitst : tglobalsymtable;
  632. {$ifdef GDB}
  633. pu : tused_unit;
  634. {$endif GDB}
  635. store_crc,store_interface_crc : cardinal;
  636. s2 : ^string; {Saves stack space}
  637. force_init_final : boolean;
  638. begin
  639. consume(_UNIT);
  640. if token=_ID then
  641. begin
  642. { create filenames and unit name }
  643. main_file := current_scanner.inputfile;
  644. while assigned(main_file.next) do
  645. main_file := main_file.next;
  646. current_module.SetFileName(main_file.path^+main_file.name^,true);
  647. stringdispose(current_module.modulename);
  648. stringdispose(current_module.realmodulename);
  649. current_module.modulename:=stringdup(pattern);
  650. current_module.realmodulename:=stringdup(orgpattern);
  651. { check for system unit }
  652. new(s2);
  653. s2^:=upper(SplitName(main_file.name^));
  654. if (cs_check_unit_name in aktglobalswitches) and
  655. not((current_module.modulename^=s2^) or
  656. ((length(current_module.modulename^)>8) and
  657. (copy(current_module.modulename^,1,8)=s2^))) then
  658. Message1(unit_e_illegal_unit_name,current_module.realmodulename^);
  659. if (current_module.modulename^='SYSTEM') then
  660. include(aktmoduleswitches,cs_compilesystem);
  661. dispose(s2);
  662. end;
  663. consume(_ID);
  664. consume(_SEMICOLON);
  665. consume(_INTERFACE);
  666. { global switches are read, so further changes aren't allowed }
  667. current_module.in_global:=false;
  668. { handle the global switches }
  669. setupglobalswitches;
  670. Message1(unit_u_start_parse_interface,current_module.realmodulename^);
  671. { update status }
  672. status.currentmodule:=current_module.realmodulename^;
  673. { maybe turn off m_objpas if we are compiling objpas }
  674. if (current_module.modulename^='OBJPAS') then
  675. exclude(aktmodeswitches,m_objpas);
  676. { this should be placed after uses !!}
  677. {$ifndef UseNiceNames}
  678. procprefix:='_'+current_module.modulename^+'$$';
  679. {$else UseNiceNames}
  680. procprefix:='_'+tostr(length(current_module.modulename^))+lowercase(current_module.modulename^)+'_';
  681. {$endif UseNiceNames}
  682. parse_only:=true;
  683. { generate now the global symboltable }
  684. st:=tglobalsymtable.create(current_module.modulename^);
  685. refsymtable:=st;
  686. unitst:=tglobalsymtable(st);
  687. { define first as local to overcome dependency conflicts }
  688. current_module.localsymtable:=st;
  689. { the unit name must be usable as a unit specifier }
  690. { inside the unit itself (PM) }
  691. { this also forbids to have another symbol }
  692. { with the same name as the unit }
  693. refsymtable.insert(tunitsym.create(current_module.realmodulename^,unitst));
  694. { load default units, like the system unit }
  695. loaddefaultunits;
  696. { reset }
  697. make_ref:=true;
  698. lexlevel:=0;
  699. { insert qualifier for the system unit (allows system.writeln) }
  700. if not(cs_compilesystem in aktmoduleswitches) then
  701. begin
  702. if token=_USES then
  703. begin
  704. loadunits;
  705. { has it been compiled at a higher level ?}
  706. if current_module.compiled then
  707. begin
  708. { this unit symtable is obsolete }
  709. { dispose(unitst,done);
  710. disposed as localsymtable !! }
  711. RestoreUnitSyms;
  712. exit;
  713. end;
  714. end;
  715. { ... but insert the symbol table later }
  716. st.next:=symtablestack;
  717. symtablestack:=st;
  718. end
  719. else
  720. { while compiling a system unit, some types are directly inserted }
  721. begin
  722. st.next:=symtablestack;
  723. symtablestack:=st;
  724. insert_intern_types(st);
  725. end;
  726. { now we know the place to insert the constants }
  727. constsymtable:=symtablestack;
  728. { move the global symtab from the temporary local to global }
  729. current_module.globalsymtable:=current_module.localsymtable;
  730. current_module.localsymtable:=nil;
  731. reset_global_defs;
  732. { number all units, so we know if a unit is used by this unit or
  733. needs to be added implicitly }
  734. current_module.numberunits;
  735. { ... parse the declarations }
  736. Message1(parser_u_parsing_interface,current_module.realmodulename^);
  737. read_interface_declarations;
  738. { leave when we got an error }
  739. if (Errorcount>0) and not status.skip_error then
  740. begin
  741. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  742. status.skip_error:=true;
  743. exit;
  744. end;
  745. {else in inteface its somatimes necessary even if unused
  746. st^.allunitsused; }
  747. {$ifdef New_GDB}
  748. write_gdb_info;
  749. {$endIf Def New_GDB}
  750. if not(cs_compilesystem in aktmoduleswitches) then
  751. if (Errorcount=0) then
  752. tppumodule(current_module).getppucrc;
  753. { Parse the implementation section }
  754. consume(_IMPLEMENTATION);
  755. current_module.in_implementation:=true;
  756. Message1(unit_u_start_parse_implementation,current_module.modulename^);
  757. parse_only:=false;
  758. { generates static symbol table }
  759. st:=tstaticsymtable.create(current_module.modulename^);
  760. current_module.localsymtable:=st;
  761. { remove the globalsymtable from the symtable stack }
  762. { to reinsert it after loading the implementation units }
  763. symtablestack:=unitst.next;
  764. { we don't want implementation units symbols in unitsymtable !! PM }
  765. refsymtable:=st;
  766. { Read the implementation units }
  767. parse_implementation_uses(unitst);
  768. if current_module.compiled then
  769. begin
  770. RestoreUnitSyms;
  771. exit;
  772. end;
  773. { reset ranges/stabs in exported definitions }
  774. reset_global_defs;
  775. { All units are read, now give them a number }
  776. current_module.numberunits;
  777. { now we can change refsymtable }
  778. refsymtable:=st;
  779. { but reinsert the global symtable as lasts }
  780. unitst.next:=symtablestack;
  781. symtablestack:=unitst;
  782. tstoredsymtable(symtablestack).chainoperators;
  783. {$ifdef DEBUG}
  784. test_symtablestack;
  785. {$endif DEBUG}
  786. constsymtable:=symtablestack;
  787. {$ifdef Splitheap}
  788. if testsplit then
  789. begin
  790. Split_Heap;
  791. allow_special:=true;
  792. Switch_to_temp_heap;
  793. end;
  794. { it will report all crossings }
  795. allow_special:=false;
  796. {$endif Splitheap}
  797. Message1(parser_u_parsing_implementation,current_module.realmodulename^);
  798. { Compile the unit }
  799. codegen_newprocedure;
  800. gen_main_procsym(current_module.modulename^+'_init',potype_unitinit,st);
  801. aktprocsym.definition.aliasnames.insert('INIT$$'+current_module.modulename^);
  802. aktprocsym.definition.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_init');
  803. compile_proc_body(true,false);
  804. codegen_doneprocedure;
  805. { avoid self recursive destructor call !! PM }
  806. aktprocsym.definition.localst:=nil;
  807. { if the unit contains ansi/widestrings, initialization and
  808. finalization code must be forced }
  809. force_init_final:=tglobalsymtable(current_module.globalsymtable).needs_init_final or
  810. tstaticsymtable(current_module.localsymtable).needs_init_final;
  811. { should we force unit initialization? }
  812. { this is a hack, but how can it be done better ? }
  813. if force_init_final and ((current_module.flags and uf_init)=0) then
  814. begin
  815. current_module.flags:=current_module.flags or uf_init;
  816. { now we can insert a cut }
  817. if (cs_create_smart in aktmoduleswitches) then
  818. codeSegment.concat(Tai_cut.Create);
  819. genimplicitunitinit(codesegment);
  820. end;
  821. { finalize? }
  822. if token=_FINALIZATION then
  823. begin
  824. { set module options }
  825. current_module.flags:=current_module.flags or uf_finalize;
  826. { Compile the finalize }
  827. codegen_newprocedure;
  828. gen_main_procsym(current_module.modulename^+'_finalize',potype_unitfinalize,st);
  829. aktprocsym.definition.aliasnames.insert('FINALIZE$$'+current_module.modulename^);
  830. aktprocsym.definition.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_finalize');
  831. compile_proc_body(true,false);
  832. codegen_doneprocedure;
  833. end
  834. else if force_init_final then
  835. begin
  836. current_module.flags:=current_module.flags or uf_finalize;
  837. { now we can insert a cut }
  838. if (cs_create_smart in aktmoduleswitches) then
  839. codeSegment.concat(Tai_cut.Create);
  840. genimplicitunitfinal(codesegment);
  841. end;
  842. { the last char should always be a point }
  843. consume(_POINT);
  844. If ResourceStrings.ResStrCount>0 then
  845. begin
  846. ResourceStrings.CreateResourceStringList;
  847. current_module.flags:=current_module.flags or uf_has_resources;
  848. { only write if no errors found }
  849. if (Errorcount=0) then
  850. ResourceStrings.WriteResourceFile(ForceExtension(current_module.ppufilename^,'.rst'));
  851. end;
  852. { avoid self recursive destructor call !! PM }
  853. aktprocsym.definition.localst:=nil;
  854. { absence does not matter here !! }
  855. aktprocsym.definition.forwarddef:=false;
  856. { test static symtable }
  857. if (Errorcount=0) then
  858. begin
  859. tstoredsymtable(st).allsymbolsused;
  860. tstoredsymtable(st).allunitsused;
  861. tstoredsymtable(st).allprivatesused;
  862. end;
  863. { size of the static data }
  864. datasize:=st.datasize;
  865. {$ifdef GDB}
  866. { add all used definitions even for implementation}
  867. if (cs_debuginfo in aktmoduleswitches) then
  868. begin
  869. {$IfnDef New_GDB}
  870. if assigned(current_module.globalsymtable) then
  871. begin
  872. { all types }
  873. tglobalsymtable(current_module.globalsymtable).concattypestabto(debuglist);
  874. { and all local symbols}
  875. tglobalsymtable(current_module.globalsymtable).concatstabto(debuglist);
  876. end;
  877. { all local types }
  878. tglobalsymtable(st)^.concattypestabto(debuglist);
  879. { and all local symbols}
  880. st^.concatstabto(debuglist);
  881. {$else New_GDB}
  882. write_gdb_info;
  883. {$endIf Def New_GDB}
  884. end;
  885. {$endif GDB}
  886. reset_global_defs;
  887. { tests, if all (interface) forwards are resolved }
  888. if (Errorcount=0) then
  889. begin
  890. tstoredsymtable(symtablestack).check_forwards;
  891. tstoredsymtable(symtablestack).allprivatesused;
  892. end;
  893. current_module.in_implementation:=false;
  894. {$ifdef GDB}
  895. tglobalsymtable(symtablestack).is_stab_written:=false;
  896. {$endif GDB}
  897. { leave when we got an error }
  898. if (Errorcount>0) and not status.skip_error then
  899. begin
  900. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  901. status.skip_error:=true;
  902. exit;
  903. end;
  904. { generate imports }
  905. if current_module.uses_imports then
  906. importlib.generatelib;
  907. { insert own objectfile, or say that it's in a library
  908. (no check for an .o when loading) }
  909. if is_assembler_generated then
  910. insertobjectfile
  911. else
  912. current_module.flags:=current_module.flags or uf_no_link;
  913. if cs_local_browser in aktmoduleswitches then
  914. current_module.localsymtable:=refsymtable;
  915. {$ifdef GDB}
  916. pu:=tused_unit(usedunits.first);
  917. while assigned(pu) do
  918. begin
  919. if assigned(pu.u.globalsymtable) then
  920. tglobalsymtable(pu.u.globalsymtable).is_stab_written:=false;
  921. pu:=tused_unit(pu.next);
  922. end;
  923. {$endif GDB}
  924. if is_assembler_generated then
  925. begin
  926. { finish asmlist by adding segment starts }
  927. insertsegment;
  928. { assemble }
  929. create_objectfile;
  930. end;
  931. { Write out the ppufile after the object file has been created }
  932. store_interface_crc:=current_module.interface_crc;
  933. store_crc:=current_module.crc;
  934. if (Errorcount=0) then
  935. tppumodule(current_module).writeppu;
  936. {$ifdef EXTDEBUG}
  937. if store_interface_crc<>current_module.interface_crc then
  938. Comment(V_Warning,current_module.ppufilename^+' Interface CRC changed '+
  939. hexstr(store_crc,8)+'<>'+hexstr(current_module.interface_crc,8));
  940. if (store_crc<>current_module.crc) and simplify_ppu then
  941. Comment(V_Warning,current_module.ppufilename^+' implementation CRC changed '+
  942. hexstr(store_crc,8)+'<>'+hexstr(current_module.interface_crc,8));
  943. {$endif EXTDEBUG}
  944. { remove static symtable (=refsymtable) here to save some mem }
  945. if not (cs_local_browser in aktmoduleswitches) then
  946. begin
  947. st.free;
  948. current_module.localsymtable:=nil;
  949. end;
  950. RestoreUnitSyms;
  951. { leave when we got an error }
  952. if (Errorcount>0) and not status.skip_error then
  953. begin
  954. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  955. status.skip_error:=true;
  956. exit;
  957. end;
  958. end;
  959. procedure proc_program(islibrary : boolean);
  960. var
  961. main_file: tinputfile;
  962. st : tsymtable;
  963. hp : tmodule;
  964. begin
  965. DLLsource:=islibrary;
  966. IsExe:=true;
  967. parse_only:=false;
  968. { relocation works only without stabs under win32 !! PM }
  969. { internal assembler uses rva for stabs info
  970. so it should work with relocated DLLs }
  971. if RelocSection and
  972. (target_info.target=target_i386_win32) and
  973. (target_info.assem<>as_i386_pecoff) then
  974. begin
  975. include(aktglobalswitches,cs_link_strip);
  976. { Warning stabs info does not work with reloc section !! }
  977. if cs_debuginfo in aktmoduleswitches then
  978. begin
  979. Message1(parser_w_parser_reloc_no_debug,current_module.mainsource^);
  980. Message(parser_w_parser_win32_debug_needs_WN);
  981. exclude(aktmoduleswitches,cs_debuginfo);
  982. end;
  983. end;
  984. { get correct output names }
  985. main_file := current_scanner.inputfile;
  986. while assigned(main_file.next) do
  987. main_file := main_file.next;
  988. current_module.SetFileName(main_file.path^+main_file.name^,true);
  989. if islibrary then
  990. begin
  991. consume(_LIBRARY);
  992. stringdispose(current_module.modulename);
  993. current_module.modulename:=stringdup(pattern);
  994. current_module.islibrary:=true;
  995. exportlib.preparelib(pattern);
  996. consume(_ID);
  997. consume(_SEMICOLON);
  998. end
  999. else
  1000. { is there an program head ? }
  1001. if token=_PROGRAM then
  1002. begin
  1003. consume(_PROGRAM);
  1004. stringdispose(current_module.modulename);
  1005. stringdispose(current_module.realmodulename);
  1006. current_module.modulename:=stringdup(pattern);
  1007. current_module.realmodulename:=stringdup(orgpattern);
  1008. if (target_info.target=target_i386_WIN32) then
  1009. exportlib.preparelib(pattern);
  1010. consume(_ID);
  1011. if token=_LKLAMMER then
  1012. begin
  1013. consume(_LKLAMMER);
  1014. consume_idlist;
  1015. consume(_RKLAMMER);
  1016. end;
  1017. consume(_SEMICOLON);
  1018. end
  1019. else if (target_info.target=target_i386_WIN32) then
  1020. exportlib.preparelib(current_module.modulename^);
  1021. { global switches are read, so further changes aren't allowed }
  1022. current_module.in_global:=false;
  1023. { setup things using the global switches }
  1024. setupglobalswitches;
  1025. { set implementation flag }
  1026. current_module.in_implementation:=true;
  1027. { insert after the unit symbol tables the static symbol table }
  1028. { of the program }
  1029. st:=tstaticsymtable.create(current_module.modulename^);;
  1030. current_module.localsymtable:=st;
  1031. refsymtable:=st;
  1032. { load standard units (system,objpas,profile unit) }
  1033. loaddefaultunits;
  1034. { reset }
  1035. lexlevel:=0;
  1036. {Load the units used by the program we compile.}
  1037. if token=_USES then
  1038. loadunits;
  1039. tstoredsymtable(symtablestack).chainoperators;
  1040. { reset ranges/stabs in exported definitions }
  1041. reset_global_defs;
  1042. { All units are read, now give them a number }
  1043. current_module.numberunits;
  1044. {Insert the name of the main program into the symbol table.}
  1045. if current_module.realmodulename^<>'' then
  1046. st.insert(tunitsym.create(current_module.realmodulename^,tglobalsymtable(st)));
  1047. { ...is also constsymtable, this is the symtable where }
  1048. { the elements of enumeration types are inserted }
  1049. constsymtable:=st;
  1050. Message1(parser_u_parsing_implementation,current_module.mainsource^);
  1051. { reset }
  1052. procprefix:='';
  1053. {The program intialization needs an alias, so it can be called
  1054. from the bootstrap code.}
  1055. codegen_newprocedure;
  1056. if islibrary then
  1057. begin
  1058. gen_main_procsym(current_module.modulename^+'_main',potype_proginit,st);
  1059. aktprocsym.definition.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_main');
  1060. aktprocsym.definition.aliasnames.insert('PASCALMAIN');
  1061. { this code is called from C so we need to save some
  1062. registers }
  1063. include(aktprocsym.definition.procoptions,po_savestdregs);
  1064. end
  1065. else
  1066. begin
  1067. gen_main_procsym('main',potype_proginit,st);
  1068. aktprocsym.definition.aliasnames.insert('program_init');
  1069. aktprocsym.definition.aliasnames.insert('PASCALMAIN');
  1070. aktprocsym.definition.aliasnames.insert(target_info.cprefix+'main');
  1071. {$ifdef m68k}
  1072. if target_info.target=target_m68k_PalmOS then
  1073. aktprocsym.definition.aliasnames.insert('PilotMain');
  1074. {$endif m68k}
  1075. end;
  1076. compile_proc_body(true,false);
  1077. { Add symbol to the exports section for win32 so smartlinking a
  1078. DLL will include the edata section }
  1079. if assigned(exportlib) and
  1080. (target_info.target=target_i386_win32) and
  1081. assigned(current_module._exports.first) then
  1082. codesegment.concat(tai_const_symbol.create(exportlib.edatalabel));
  1083. { avoid self recursive destructor call !! PM }
  1084. aktprocsym.definition.localst:=nil;
  1085. { consider these symbols as global ones for browser
  1086. but the typecasting of the globalsymtable with tglobalsymtable
  1087. can then lead to problems (PFV)
  1088. current_module.globalsymtable:=current_module.localsymtable;
  1089. current_module.localsymtable:=nil;}
  1090. If ResourceStrings.ResStrCount>0 then
  1091. begin
  1092. ResourceStrings.CreateResourceStringList;
  1093. { only write if no errors found }
  1094. if (Errorcount=0) then
  1095. ResourceStrings.WriteResourceFile(ForceExtension(current_module.ppufilename^,'.rst'));
  1096. end;
  1097. codegen_doneprocedure;
  1098. { finalize? }
  1099. if token=_FINALIZATION then
  1100. begin
  1101. { set module options }
  1102. current_module.flags:=current_module.flags or uf_finalize;
  1103. { Compile the finalize }
  1104. codegen_newprocedure;
  1105. gen_main_procsym(current_module.modulename^+'_finalize',potype_unitfinalize,st);
  1106. aktprocsym.definition.aliasnames.insert('FINALIZE$$'+current_module.modulename^);
  1107. aktprocsym.definition.aliasnames.insert(target_info.cprefix+current_module.modulename^+'_finalize');
  1108. compile_proc_body(true,false);
  1109. codegen_doneprocedure;
  1110. end;
  1111. { consume the last point }
  1112. consume(_POINT);
  1113. {$ifdef New_GDB}
  1114. write_gdb_info;
  1115. {$endIf Def New_GDB}
  1116. { leave when we got an error }
  1117. if (Errorcount>0) and not status.skip_error then
  1118. begin
  1119. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1120. status.skip_error:=true;
  1121. exit;
  1122. end;
  1123. { test static symtable }
  1124. if (Errorcount=0) then
  1125. begin
  1126. tstoredsymtable(st).allsymbolsused;
  1127. tstoredsymtable(st).allunitsused;
  1128. tstoredsymtable(st).allprivatesused;
  1129. end;
  1130. { generate imports }
  1131. if current_module.uses_imports then
  1132. importlib.generatelib;
  1133. if islibrary or
  1134. (target_info.target=target_i386_WIN32) then
  1135. exportlib.generatelib;
  1136. { insert heap }
  1137. insertResourceTablesTable;
  1138. insertinitfinaltable;
  1139. insertheap;
  1140. inserttargetspecific;
  1141. datasize:=symtablestack.datasize;
  1142. { finish asmlist by adding segment starts }
  1143. insertsegment;
  1144. { insert own objectfile }
  1145. insertobjectfile;
  1146. { assemble and link }
  1147. create_objectfile;
  1148. { leave when we got an error }
  1149. if (Errorcount>0) and not status.skip_error then
  1150. begin
  1151. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1152. status.skip_error:=true;
  1153. exit;
  1154. end;
  1155. { create the executable when we are at level 1 }
  1156. if (compile_level=1) then
  1157. begin
  1158. { insert all .o files from all loaded units }
  1159. hp:=tmodule(loaded_units.first);
  1160. while assigned(hp) do
  1161. begin
  1162. linker.AddModuleFiles(hp);
  1163. hp:=tmodule(hp.next);
  1164. end;
  1165. { write .def file }
  1166. if (cs_link_deffile in aktglobalswitches) then
  1167. deffile.writefile;
  1168. { finally we can create a executable }
  1169. if (not current_module.is_unit) then
  1170. begin
  1171. if DLLSource then
  1172. linker.MakeSharedLibrary
  1173. else
  1174. linker.MakeExecutable;
  1175. end;
  1176. end;
  1177. end;
  1178. end.
  1179. {
  1180. $Log$
  1181. Revision 1.39 2001-08-01 15:07:29 jonas
  1182. + "compilerproc" directive support, which turns both the public and mangled
  1183. name to lowercase(declaration_name). This prevents a normal user from
  1184. accessing the routine, but they can still be easily looked up within
  1185. the compiler. This is used for helper procedures and should facilitate
  1186. the writing of more processor independent code in the code generator
  1187. itself (mostly written by Peter)
  1188. + new "createintern" constructor for tcal nodes to create a call to
  1189. helper exported using the "compilerproc" directive
  1190. + support for high(dynamic_array) using the the above new things
  1191. + definition of 'HASCOMPILERPROC' symbol (to be able to check in the
  1192. compiler and rtl whether the "compilerproc" directive is supported)
  1193. Revision 1.38 2001/07/30 20:59:27 peter
  1194. * m68k updates from v10 merged
  1195. Revision 1.37 2001/06/18 20:36:25 peter
  1196. * -Ur switch (merged)
  1197. * masm fixes (merged)
  1198. * quoted filenames for go32v2 and win32
  1199. Revision 1.36 2001/06/06 21:58:16 peter
  1200. * Win32 fixes for Makefile so it doesn't require sh.exe
  1201. Revision 1.35 2001/06/03 21:57:36 peter
  1202. + hint directive parsing support
  1203. Revision 1.34 2001/06/03 15:15:31 peter
  1204. * dllprt0 stub for linux shared libs
  1205. * pass -init and -fini for linux shared libs
  1206. * libprefix splitted into staticlibprefix and sharedlibprefix
  1207. Revision 1.33 2001/05/19 23:05:19 peter
  1208. * support uses <unit> in <file> construction
  1209. Revision 1.32 2001/05/18 22:26:36 peter
  1210. * merged alignment for non-i386
  1211. Revision 1.31 2001/05/09 14:11:10 jonas
  1212. * range check error fixes from Peter
  1213. Revision 1.30 2001/05/06 14:49:17 peter
  1214. * ppu object to class rewrite
  1215. * move ppu read and write stuff to fppu
  1216. Revision 1.29 2001/04/18 22:01:57 peter
  1217. * registration of targets and assemblers
  1218. Revision 1.28 2001/04/13 18:08:37 peter
  1219. * scanner object to class
  1220. Revision 1.27 2001/04/13 01:22:12 peter
  1221. * symtable change to classes
  1222. * range check generation and errors fixed, make cycle DEBUG=1 works
  1223. * memory leaks fixed
  1224. Revision 1.26 2001/04/02 21:20:33 peter
  1225. * resulttype rewrite
  1226. Revision 1.25 2001/03/13 18:45:07 peter
  1227. * fixed some memory leaks
  1228. Revision 1.24 2001/03/06 18:28:02 peter
  1229. * patch from Pavel with a new and much faster DLL Scanner for
  1230. automatic importing so $linklib works for DLLs. Thanks Pavel!
  1231. Revision 1.23 2001/02/24 10:44:56 peter
  1232. * generate .rst from ppufilename instead of modulename
  1233. Revision 1.22 2001/02/21 19:37:19 peter
  1234. * moved deref to be done after loading of implementation units. prederef
  1235. is still done directly after loading of symbols and definitions.
  1236. Revision 1.21 2001/01/14 22:13:52 peter
  1237. * fixed crash with program name as a important unit name
  1238. Revision 1.20 2000/12/25 00:07:27 peter
  1239. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1240. tlinkedlist objects)
  1241. Revision 1.19 2000/11/29 00:30:36 florian
  1242. * unused units removed from uses clause
  1243. * some changes for widestrings
  1244. Revision 1.18 2000/11/01 23:04:37 peter
  1245. * tprocdef.fullprocname added for better casesensitve writing of
  1246. procedures
  1247. Revision 1.17 2000/10/31 22:02:50 peter
  1248. * symtable splitted, no real code changes
  1249. Revision 1.16 2000/10/21 14:36:26 peter
  1250. * merged pierres fixes
  1251. Revision 1.15 2000/10/15 09:08:58 peter
  1252. * use System for the systemunit instead of target dependent
  1253. Revision 1.14 2000/10/15 07:47:51 peter
  1254. * unit names and procedure names are stored mixed case
  1255. Revision 1.13 2000/10/04 14:51:08 pierre
  1256. * IsExe restored
  1257. Revision 1.12 2000/09/30 16:07:40 peter
  1258. * filepos when unit not found (merged)
  1259. Revision 1.11 2000/09/24 21:33:47 peter
  1260. * message updates merges
  1261. Revision 1.10 2000/09/24 15:06:22 peter
  1262. * use defines.inc
  1263. Revision 1.9 2000/08/31 07:53:02 michael
  1264. + Applied patch from Peter
  1265. Revision 1.8 2000/08/29 19:00:01 peter
  1266. * _init and _finalize procsyms also need a $ prefix
  1267. Revision 1.7 2000/08/27 20:19:39 peter
  1268. * store strings with case in ppu, when an internal symbol is created
  1269. a '$' is prefixed so it's not automatic uppercased
  1270. Revision 1.6 2000/08/27 16:11:52 peter
  1271. * moved some util functions from globals,cobjects to cutils
  1272. * splitted files into finput,fmodule
  1273. Revision 1.5 2000/08/25 08:48:22 jonas
  1274. * fixed bug with include files at the very beginning of .pp/.pas files
  1275. (wrong name used for generating exe/checking unit name) (merged from
  1276. fixes branch)
  1277. Revision 1.4 2000/08/21 11:27:44 pierre
  1278. * fix the stabs problems
  1279. Revision 1.3 2000/07/13 12:08:26 michael
  1280. + patched to 1.1.0 with former 1.09patch from peter
  1281. Revision 1.2 2000/07/13 11:32:45 michael
  1282. + removed logs
  1283. }