pmodules.pas 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067
  1. {
  2. Copyright (c) 1998-2008 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. uses fmodule;
  21. function proc_unit(curr: tmodule):boolean;
  22. function parse_unit_interface_declarations(curr : tmodule) : boolean;
  23. function proc_unit_implementation(curr: tmodule):boolean;
  24. function proc_package(curr: tmodule) : boolean;
  25. function proc_program(curr: tmodule; islibrary : boolean) : boolean;
  26. function proc_program_declarations(curr : tmodule; islibrary : boolean) : boolean;
  27. function finish_compile_unit(module:tmodule): boolean;
  28. function finish_unit(module:tmodule): boolean;
  29. implementation
  30. uses
  31. SysUtils,
  32. globtype,systems,tokens,
  33. cutils,cfileutl,cclasses,comphook,
  34. globals,verbose,finput,fppu,globstat,fpcp,fpkg,
  35. symconst,symbase,symtype,symdef,symsym,symtable,defutil,symcreat,
  36. wpoinfo,
  37. aasmtai,aasmdata,aasmbase,aasmcpu,
  38. cgbase,ngenutil,
  39. nbas,nutils,ncgutil,
  40. link,assemble,import,export,gendef,ppu,comprsrc,dbgbase,
  41. cresstr,procinfo,
  42. objcgutl,
  43. pkgutil,
  44. wpobase,
  45. scanner,pbase,pexpr,psystem,psub,pgenutil,pparautl,ncgvmt,ncgrtti,
  46. ctask,
  47. cpuinfo;
  48. procedure create_objectfile(curr : tmodule);
  49. var
  50. DLLScanner : TDLLScanner;
  51. s : string;
  52. KeepShared : TCmdStrList;
  53. begin
  54. { try to create import entries from system dlls }
  55. if (tf_has_dllscanner in target_info.flags) and
  56. (not curr.linkOtherSharedLibs.Empty) then
  57. begin
  58. { Init DLLScanner }
  59. if assigned(CDLLScanner[target_info.system]) then
  60. DLLScanner:=CDLLScanner[target_info.system].Create
  61. else
  62. internalerror(200104121);
  63. KeepShared:=TCmdStrList.Create;
  64. { Walk all shared libs }
  65. While not curr.linkOtherSharedLibs.Empty do
  66. begin
  67. S:=curr.linkOtherSharedLibs.Getusemask(link_always);
  68. if not DLLScanner.scan(s) then
  69. KeepShared.Concat(s);
  70. end;
  71. DLLscanner.Free;
  72. DLLscanner := nil;
  73. { Recreate import section }
  74. if (target_info.system in [system_i386_win32,system_i386_wdosx]) then
  75. begin
  76. if assigned(current_asmdata.asmlists[al_imports]) then
  77. current_asmdata.asmlists[al_imports].clear
  78. else
  79. current_asmdata.asmlists[al_imports]:=TAsmList.Create;
  80. importlib.generatelib;
  81. end;
  82. { Readd the not processed files }
  83. while not KeepShared.Empty do
  84. begin
  85. s:=KeepShared.GetFirst;
  86. curr.linkOtherSharedLibs.add(s,link_always);
  87. end;
  88. KeepShared.Free;
  89. KeepShared := nil;
  90. end;
  91. { allow a target-specific pass over all assembler code (used by LLVM
  92. to insert type definitions }
  93. cnodeutils.InsertObjectInfo;
  94. { Start and end module debuginfo, at least required for stabs
  95. to insert n_sourcefile lines }
  96. if (cs_debuginfo in current_settings.moduleswitches) or
  97. (cs_use_lineinfo in current_settings.globalswitches) then
  98. current_debuginfo.insertmoduleinfo;
  99. { create the .s file and assemble it }
  100. if not(create_smartlink_library) or not(tf_no_objectfiles_when_smartlinking in target_info.flags) then
  101. GenerateAsm(false);
  102. { Also create a smartlinked version ? }
  103. if create_smartlink_library then
  104. begin
  105. GenerateAsm(true);
  106. if (af_needar in target_asm.flags) then
  107. Linker.MakeStaticLibrary;
  108. end;
  109. { resource files }
  110. CompileResourceFiles;
  111. end;
  112. procedure insertobjectfile(curr : tmodule);
  113. { Insert the used object file for this unit in the used list for this unit }
  114. begin
  115. curr.linkunitofiles.add(curr.objfilename,link_static);
  116. curr.headerflags:=curr.headerflags or uf_static_linked;
  117. if create_smartlink_library then
  118. begin
  119. curr.linkunitstaticlibs.add(curr.staticlibfilename ,link_smart);
  120. curr.headerflags:=curr.headerflags or uf_smart_linked;
  121. end;
  122. if cs_lto in current_settings.moduleswitches then
  123. begin
  124. curr.linkunitofiles.add(ChangeFileExt(curr.objfilename,LTOExt),link_lto);
  125. curr.headerflags:=curr.headerflags or uf_lto_linked;
  126. end;
  127. end;
  128. procedure create_dwarf_frame;
  129. begin
  130. { Dwarf conflicts with smartlinking in separate .a files }
  131. if create_smartlink_library then
  132. exit;
  133. { Call frame information }
  134. { MWE: we write our own info, so dwarf asm support is not really needed }
  135. { if (af_supports_dwarf in target_asm.flags) and }
  136. { CFI is currently broken for Darwin }
  137. if not(target_info.system in systems_darwin) and
  138. (
  139. (tf_needs_dwarf_cfi in target_info.flags) or
  140. (target_dbg.id in [dbg_dwarf2, dbg_dwarf3])
  141. ) then
  142. begin
  143. current_asmdata.asmlists[al_dwarf_frame].Free;
  144. current_asmdata.asmlists[al_dwarf_frame] := TAsmList.create;
  145. current_asmdata.asmcfi.generate_code(current_asmdata.asmlists[al_dwarf_frame]);
  146. end;
  147. end;
  148. Function CheckResourcesUsed(curr : tmodule) : boolean;
  149. var
  150. hp : tused_unit;
  151. found : Boolean;
  152. begin
  153. CheckResourcesUsed:=tf_has_winlike_resources in target_info.flags;
  154. if not CheckResourcesUsed then exit;
  155. hp:=tused_unit(usedunits.first);
  156. found:=mf_has_resourcefiles in curr.moduleflags;
  157. while Assigned(hp) and not found do
  158. begin
  159. found:=mf_has_resourcefiles in hp.u.moduleflags;
  160. hp:=tused_unit(hp.next);
  161. end;
  162. CheckResourcesUsed:=found;
  163. end;
  164. function AddUnit(curr : tmodule; const s:string;addasused:boolean): tppumodule;
  165. var
  166. hp : tppumodule;
  167. unitsym : tunitsym;
  168. isnew,load_ok : boolean;
  169. uu: tused_unit;
  170. begin
  171. { load unit }
  172. hp:=registerunit(curr,s,'',isnew);
  173. if isnew then
  174. usedunits.concat(tused_unit.create(hp,true,addasused,nil));
  175. load_ok:=hp.loadppu(curr);
  176. if not load_ok then
  177. { We must schedule a compile. }
  178. task_handler.addmodule(hp);
  179. hp.adddependency(curr,curr.in_interface);
  180. { add to symtable stack }
  181. if assigned(hp.globalsymtable) then
  182. symtablestack.push(hp.globalsymtable);
  183. if (m_mac in current_settings.modeswitches) and
  184. assigned(hp.globalmacrosymtable) then
  185. macrosymtablestack.push(hp.globalmacrosymtable);
  186. { insert unitsym }
  187. unitsym:=cunitsym.create(hp.modulename^,hp);
  188. inc(unitsym.refs);
  189. tabstractunitsymtable(curr.localsymtable).insertunit(unitsym);
  190. if addasused then
  191. begin
  192. { add to used units }
  193. uu:=curr.addusedunit(hp,false,unitsym);
  194. {$IFDEF EnableCTaskPPU}
  195. uu.dependent_added:=true;
  196. {$ENDIF}
  197. end;
  198. result:=hp;
  199. end;
  200. function AddUnit(curr :tmodule; const s:string):tppumodule;
  201. begin
  202. result:=AddUnit(curr,s,true);
  203. end;
  204. function maybeloadvariantsunit(curr : tmodule) : boolean;
  205. var
  206. hp : tmodule;
  207. addsystemnamespace : Boolean;
  208. begin
  209. result:=true;
  210. { Do we need the variants unit? Skip this
  211. for VarUtils unit for bootstrapping }
  212. if not(mf_uses_variants in curr.moduleflags) or
  213. (curr.modulename^='VARUTILS') or
  214. (curr.modulename^='SYSTEM.VARUTILS') then
  215. exit;
  216. { Variants unit already loaded? }
  217. hp:=tmodule(loaded_units.first);
  218. while assigned(hp) do
  219. begin
  220. if (hp.modulename^='VARIANTS') or (hp.modulename^='SYSTEM.VARIANTS') then
  221. exit;
  222. hp:=tmodule(hp.next);
  223. end;
  224. { Variants unit is not loaded yet, load it now }
  225. Message(parser_w_implicit_uses_of_variants_unit);
  226. addsystemnamespace:=namespacelist.Find('System')=Nil;
  227. if addsystemnamespace then
  228. namespacelist.concat('System');
  229. result:=AddUnit(curr,'variants').state in [ms_compiled,ms_processed];
  230. if addsystemnamespace then
  231. namespacelist.Remove('System');
  232. end;
  233. function MaybeRemoveResUnit(curr : tmodule) : boolean;
  234. var
  235. resources_used : boolean;
  236. hp : tmodule;
  237. uu : tused_unit;
  238. unitname : shortstring;
  239. begin
  240. { We simply remove the unit from:
  241. - usedunit list, so that things like init/finalization table won't
  242. contain references to this unit
  243. - loaded_units list, so that the unit object file doesn't get linked
  244. with the executable. }
  245. { Note: on windows we always need resources! }
  246. resources_used:=(target_info.system in systems_all_windows)
  247. or CheckResourcesUsed(curr);
  248. if (not resources_used) and (tf_has_winlike_resources in target_info.flags) then
  249. begin
  250. { resources aren't used, so we don't need this unit }
  251. if target_res.id=res_ext then
  252. unitname:='FPEXTRES'
  253. else
  254. unitname:='FPINTRES';
  255. Message1(unit_u_unload_resunit,unitname);
  256. { find the module }
  257. hp:=tmodule(loaded_units.first);
  258. while assigned(hp) do
  259. begin
  260. if hp.is_unit and (hp.modulename^=unitname) then break;
  261. hp:=tmodule(hp.next);
  262. end;
  263. if not assigned(hp) then
  264. internalerror(200801071);
  265. { find its tused_unit in the global list }
  266. uu:=tused_unit(usedunits.first);
  267. while assigned(uu) do
  268. begin
  269. if uu.u=hp then break;
  270. uu:=tused_unit(uu.next);
  271. end;
  272. if not assigned(uu) then
  273. internalerror(200801072);
  274. { remove the tused_unit }
  275. usedunits.Remove(uu);
  276. uu.Free;
  277. // Remove from local list
  278. uu:=tused_unit(curr.used_units.first);
  279. while assigned(uu) do
  280. begin
  281. if uu.u=hp then break;
  282. uu:=tused_unit(uu.next);
  283. end;
  284. if not assigned(uu) then
  285. internalerror(2024020701);
  286. curr.used_units.Remove(uu);
  287. uu.Free;
  288. uu := nil;
  289. { remove the module }
  290. loaded_units.Remove(hp);
  291. unloaded_units.Concat(hp);
  292. end;
  293. MaybeRemoveResUnit:=resources_used;
  294. end;
  295. function loadsystemunit(curr : tmodule) : boolean;
  296. var
  297. state: tglobalstate;
  298. sys : tmodule;
  299. begin
  300. Result:=False;
  301. { we are going to rebuild the symtablestack, clear it first }
  302. symtablestack.clear;
  303. macrosymtablestack.clear;
  304. { macro symtable }
  305. macrosymtablestack.push(initialmacrosymtable);
  306. { are we compiling the system unit? }
  307. if (cs_compilesystem in current_settings.moduleswitches) then
  308. begin
  309. systemunit:=tglobalsymtable(curr.localsymtable);
  310. { create system defines }
  311. create_intern_types;
  312. create_intern_symbols;
  313. { Set the owner of errorsym and errortype to symtable to
  314. prevent crashes when accessing .owner }
  315. generrorsym.owner:=systemunit;
  316. generrordef.owner:=systemunit;
  317. exit;
  318. end;
  319. { insert the system unit, it is always the first. Load also the
  320. internal types from the system unit }
  321. Sys:=AddUnit(curr,'system');
  322. Result:=Assigned(Sys) and (Sys.State in [ms_processed,ms_compiled]);
  323. systemunit:=tglobalsymtable(symtablestack.top);
  324. { load_intern_types resets the scanner... }
  325. current_scanner.tempcloseinputfile;
  326. state:=tglobalstate.create;
  327. load_intern_types;
  328. state.restore;
  329. FreeAndNil(state);
  330. current_scanner.tempopeninputfile;
  331. { Set the owner of errorsym and errortype to symtable to
  332. prevent crashes when accessing .owner }
  333. generrorsym.owner:=systemunit;
  334. generrordef.owner:=systemunit;
  335. // Implicitly enable unicode strings in unicode RTL in modes objfpc/delphi.
  336. { TODO: Check if we should also do this for mode macpas }
  337. if not (cs_compilesystem in current_settings.moduleswitches) then
  338. if ([m_objfpc,m_delphi] * current_settings.modeswitches)<>[] then
  339. if is_systemunit_unicode then
  340. Include(current_settings.modeswitches,m_default_unicodestring);
  341. { default the extended RTTI options to that of TObject }
  342. if assigned(class_tobject) then
  343. current_module.rtti_directive.options:=class_tobject.rtti.options;
  344. end;
  345. { Return true if all units were loaded, no recompilation needed. }
  346. function loaddefaultunits(curr :tmodule) : boolean;
  347. Procedure CheckAddUnit(s: string);
  348. var
  349. OK : boolean;
  350. m : TModule;
  351. begin
  352. m:=AddUnit(curr,s,true);
  353. OK:=assigned(m) and (m.state in [ms_processed,ms_compiled]);
  354. if not ok then
  355. Message2(unit_f_cant_find_ppu,s,curr.realmodulename^);
  356. Result:=ok and Result;
  357. end;
  358. begin
  359. Result:=True;
  360. { Units only required for main module }
  361. if not(curr.is_unit) then
  362. begin
  363. { Heaptrc unit, load heaptrace before any other units especially objpas }
  364. if (cs_use_heaptrc in current_settings.globalswitches) then
  365. CheckAddUnit('heaptrc');
  366. { Valgrind requires c memory manager }
  367. if (cs_gdb_valgrind in current_settings.globalswitches) or
  368. (([cs_sanitize_address]*current_settings.moduleswitches)<>[]) then
  369. CheckAddUnit('cmem');
  370. { Lineinfo unit }
  371. if (cs_use_lineinfo in current_settings.globalswitches) then begin
  372. case target_dbg.id of
  373. dbg_stabs:
  374. CheckAddUnit('lineinfo');
  375. dbg_stabx:
  376. CheckAddUnit('lnfogdb');
  377. else
  378. CheckAddUnit('lnfodwrf');
  379. end;
  380. end;
  381. {$ifdef cpufpemu}
  382. { Floating point emulation unit?
  383. softfpu must be in the system unit anyways (FK)
  384. if (cs_fp_emulation in current_settings.moduleswitches) and not(target_info.system in system_wince) then
  385. CheckAddUnit('softfpu');
  386. }
  387. {$endif cpufpemu}
  388. { Which kind of resource support?
  389. Note: if resources aren't used this unit will be removed later,
  390. otherwise we need it here since it must be loaded quite early }
  391. if (tf_has_winlike_resources in target_info.flags) then
  392. if target_res.id=res_ext then
  393. CheckAddUnit('fpextres')
  394. else
  395. CheckAddUnit('fpintres');
  396. end
  397. else if (cs_checkpointer in current_settings.localswitches) then
  398. CheckAddUnit('heaptrc');
  399. { Objpas unit? }
  400. if m_objpas in current_settings.modeswitches then
  401. CheckAddUnit('objpas');
  402. { Macpas unit? }
  403. if m_mac in current_settings.modeswitches then
  404. CheckAddUnit('macpas');
  405. if m_iso in current_settings.modeswitches then
  406. CheckAddUnit('iso7185');
  407. if m_extpas in current_settings.modeswitches then
  408. begin
  409. { basic procedures for Extended Pascal are for now provided by the iso unit }
  410. CheckAddUnit('iso7185');
  411. CheckAddUnit('extpas');
  412. end;
  413. { blocks support? }
  414. if m_blocks in current_settings.modeswitches then
  415. CheckAddUnit('blockrtl');
  416. { Determine char size. }
  417. // Ansi RTL ?
  418. if not is_systemunit_unicode then
  419. begin
  420. if m_default_unicodestring in current_settings.modeswitches then
  421. CheckAddUnit('uuchar'); // redefines char as widechar
  422. end
  423. else
  424. begin
  425. // Unicode RTL
  426. if not (m_default_ansistring in current_settings.modeswitches) then
  427. if not (curr.modulename^<>'UACHAR') then
  428. CheckAddUnit('uachar'); // redefines char as ansichar
  429. end;
  430. { Objective-C support unit? }
  431. if (m_objectivec1 in current_settings.modeswitches) then
  432. begin
  433. { interface to Objective-C run time }
  434. CheckAddUnit('objc');
  435. loadobjctypes;
  436. { NSObject }
  437. if not(curr.is_unit) or
  438. (curr.modulename^<>'OBJCBASE') then
  439. CheckAddUnit('objcbase');
  440. end;
  441. { Profile unit? Needed for go32v2 only }
  442. if (cs_profile in current_settings.moduleswitches) and
  443. (target_info.system in [system_i386_go32v2,system_i386_watcom]) then
  444. CheckAddUnit('profile');
  445. if (cs_load_fpcylix_unit in current_settings.globalswitches) then
  446. begin
  447. CheckAddUnit('fpcylix');
  448. CheckAddUnit('dynlibs');
  449. end;
  450. {$push}
  451. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  452. { CPU targets with microcontroller support can add a controller specific unit }
  453. if ControllerSupport and (target_info.system in (systems_embedded+systems_freertos)) and
  454. (current_settings.controllertype<>ct_none) and
  455. (embedded_controllers[current_settings.controllertype].controllerunitstr<>'') and
  456. (embedded_controllers[current_settings.controllertype].controllerunitstr<>curr.modulename^) then
  457. CheckAddUnit(embedded_controllers[current_settings.controllertype].controllerunitstr);
  458. {$pop}
  459. {$ifdef XTENSA}
  460. if not(curr.is_unit) and (target_info.system=system_xtensa_freertos) then
  461. if (current_settings.controllertype=ct_esp32) then
  462. begin
  463. if (idf_version>=40100) and (idf_version<40200) then
  464. CheckAddUnit('espidf_40100')
  465. else if (idf_version>=40200) and (idf_version<40400) then
  466. CheckAddUnit('espidf_40200')
  467. else if (idf_version>=40400) and (idf_version<50000) then
  468. CheckAddUnit('espidf_40400')
  469. else if (idf_version>=50000) and (idf_version<50200) then
  470. CheckAddUnit('espidf_50000')
  471. else if idf_version>=50200 then
  472. CheckAddUnit('espidf_50200')
  473. else
  474. Comment(V_Warning, 'Unsupported esp-idf version');
  475. end
  476. else if (current_settings.controllertype=ct_esp32s2) or (current_settings.controllertype=ct_esp32s3) then
  477. begin
  478. if (idf_version>=40400) and (idf_version<50000) then
  479. CheckAddUnit('espidf_40400')
  480. else if (idf_version>=50000) and (idf_version<50200) then
  481. CheckAddUnit('espidf_50000')
  482. else if idf_version>=50200 then
  483. CheckAddUnit('espidf_50200')
  484. else
  485. Message(unit_w_unsupported_esp_idf_version);
  486. end
  487. else if (current_settings.controllertype=ct_esp8266) then
  488. begin
  489. if (idf_version>=30300) and (idf_version<30400) then
  490. CheckAddUnit('esp8266rtos_30300')
  491. else if idf_version>=30400 then
  492. CheckAddUnit('esp8266rtos_30400')
  493. else
  494. Message(unit_w_unsupported_esp_idf_version);
  495. end;
  496. {$endif XTENSA}
  497. {$ifdef RISCV32}
  498. if not(curr.is_unit) and (target_info.system=system_riscv32_freertos) then
  499. if (current_settings.controllertype=ct_esp32c2) then
  500. begin
  501. if idf_version>=50200 then
  502. CheckAddUnit('esp32c2idf_50200')
  503. else if idf_version>=50000 then
  504. CheckAddUnit('esp32c2idf_50000')
  505. else if idf_version>=40400 then
  506. CheckAddUnit('esp32c2idf_40400')
  507. else
  508. Comment(V_Warning, 'Unsupported esp-idf version');
  509. end;
  510. if (current_settings.controllertype=ct_esp32c3) then
  511. begin
  512. if idf_version>=50300 then
  513. CheckAddUnit('esp32c3idf_50300')
  514. else if idf_version>=50200 then
  515. CheckAddUnit('esp32c3idf_50200')
  516. else if idf_version>=50000 then
  517. CheckAddUnit('esp32c3idf_50000')
  518. else if idf_version>=40400 then
  519. CheckAddUnit('esp32c3idf_40400')
  520. else
  521. Message(unit_w_unsupported_esp_idf_version);
  522. end;
  523. if (current_settings.controllertype=ct_esp32c6) then
  524. begin
  525. if idf_version>=50200 then
  526. CheckAddUnit('esp32c6idf_50200')
  527. else
  528. Comment(V_Warning, 'Unsupported esp-idf version');
  529. end;
  530. {$endif RISCV32}
  531. end;
  532. { Return true if all units were loaded, no recompilation needed. }
  533. function loadautounits(curr: tmodule) : boolean;
  534. Procedure CheckAddUnit(s: string);
  535. var
  536. OK : boolean;
  537. m : TModule;
  538. begin
  539. m:=AddUnit(curr,s,true);
  540. OK:=assigned(m) and (m.state in [ms_compiled,ms_processed]);
  541. Result:=ok and Result;
  542. end;
  543. var
  544. hs,s : string;
  545. begin
  546. Result:=True;
  547. hs:=autoloadunits;
  548. repeat
  549. s:=GetToken(hs,',');
  550. if s='' then
  551. break;
  552. CheckAddUnit(s);
  553. until false;
  554. end;
  555. procedure parseusesclause(curr: tmodule);
  556. var
  557. s,sorg : ansistring;
  558. fn : string;
  559. pu : tused_unit;
  560. hp2 : tmodule;
  561. unitsym : tunitsym;
  562. filepos : tfileposinfo;
  563. isnew : boolean;
  564. begin
  565. consume(_USES);
  566. repeat
  567. s:=current_scanner.pattern;
  568. sorg:=current_scanner.orgpattern;
  569. filepos:=current_tokenpos;
  570. consume(_ID);
  571. while token=_POINT do
  572. begin
  573. consume(_POINT);
  574. s:=s+'.'+current_scanner.pattern;
  575. sorg:=sorg+'.'+current_scanner.orgpattern;
  576. consume(_ID);
  577. end;
  578. { support "<unit> in '<file>'" construct, but not for tp7 }
  579. fn:='';
  580. if not(m_tp7 in current_settings.modeswitches) and
  581. try_to_consume(_OP_IN) then
  582. fn:=FixFileName(get_stringconst);
  583. { Give a warning if lineinfo is loaded }
  584. if s='LINEINFO' then
  585. begin
  586. Message(parser_w_no_lineinfo_use_switch);
  587. if (target_dbg.id in [dbg_dwarf2, dbg_dwarf3]) then
  588. s := 'LNFODWRF';
  589. sorg := s;
  590. end;
  591. { Give a warning if objpas is loaded }
  592. if s='OBJPAS' then
  593. Message(parser_w_no_objpas_use_mode);
  594. { Using the unit itself is not possible }
  595. if (s<>curr.modulename^) then
  596. begin
  597. { check if the unit is already used }
  598. hp2:=nil;
  599. pu:=tused_unit(curr.used_units.first);
  600. while assigned(pu) do
  601. begin
  602. if (pu.u.modulename^=s) then
  603. begin
  604. hp2:=pu.u;
  605. break;
  606. end;
  607. pu:=tused_unit(pu.next);
  608. end;
  609. if not assigned(hp2) then
  610. begin
  611. hp2:=registerunit(curr,sorg,fn,isnew);
  612. if isnew then
  613. usedunits.concat(tused_unit.create(hp2,curr.in_interface,true,nil));
  614. end
  615. else
  616. Message1(sym_e_duplicate_id,s);
  617. { Create unitsym, we need to use the name as specified, we
  618. can not use the modulename because that can be different
  619. when -Un is used }
  620. current_tokenpos:=filepos;
  621. unitsym:=cunitsym.create(sorg,nil);
  622. { the current module uses the unit hp2 }
  623. curr.addusedunit(hp2,true,unitsym);
  624. end
  625. else
  626. Message1(sym_e_duplicate_id,s);
  627. if token=_COMMA then
  628. begin
  629. current_scanner.pattern:='';
  630. consume(_COMMA);
  631. end
  632. else
  633. break;
  634. until false;
  635. end;
  636. function loadunits(curr: tmodule; frominterface : boolean) : boolean;
  637. var
  638. s : ansistring;
  639. pu : tused_unit;
  640. state: tglobalstate;
  641. isLoaded : Boolean;
  642. lu : tmodule;
  643. procedure restorestate;
  644. begin
  645. state.restore;
  646. if assigned(current_scanner) and (current_module.scanner=current_scanner) then
  647. begin
  648. if assigned(current_scanner.inputfile) then
  649. current_scanner.tempopeninputfile;
  650. end;
  651. state.free;
  652. state := nil;
  653. end;
  654. begin
  655. Result:=true;
  656. current_scanner.tempcloseinputfile;
  657. state:=tglobalstate.create;
  658. { Load the units }
  659. pu:=tused_unit(curr.used_units.first);
  660. while assigned(pu) do
  661. begin
  662. lu:=pu.u;
  663. { Only load the units that are in the current
  664. (interface/implementation) uses clause }
  665. if pu.in_uses and
  666. (pu.in_interface=frominterface) then
  667. begin
  668. {$IFDEF EnableCTaskPPU}
  669. // always call loadppu for the cycle test
  670. tppumodule(lu).loadppu(curr);
  671. if not (curr.state in [ms_compile,ms_compiling_wait,ms_compiling_waitintf,ms_compiling_waitimpl]) then
  672. begin
  673. {$IFDEF DEBUG_PPU_CYCLES}
  674. writeln('loadunits STOPPED ',curr.modulename^,' ',curr.statestr);
  675. {$ENDIF}
  676. Result:=false;
  677. break;
  678. end;
  679. if not pu.dependent_added then
  680. begin
  681. pu.dependent_added:=true;
  682. lu.adddependency(curr,frominterface);
  683. end;
  684. if not lu.interface_compiled or lu.do_reload then
  685. begin
  686. // an used unit is delayed
  687. // Important: load the rest of the uses section
  688. Result:=false;
  689. end;
  690. {$ELSE}
  691. if lu.interface_compiled then
  692. isLoaded:=true
  693. else if (lu.state=ms_registered) then
  694. // try to load
  695. isLoaded:=tppumodule(lu).loadppu(curr) and lu.interface_compiled
  696. else
  697. isLoaded:=False;
  698. isLoaded:=IsLoaded and not lu.is_reset ;
  699. if not IsLoaded then
  700. begin
  701. // In case of is_reset, the task handler will discard the state if the module was already there
  702. task_handler.addmodule(lu);
  703. end;
  704. IsLoaded:=Isloaded and not curr.is_reset;
  705. Result:=Result and IsLoaded;
  706. { If we were reset, then used_units is no longer correct, and we must exit at once. }
  707. if curr.is_reset then
  708. break;
  709. { is our module compiled? then we can stop }
  710. if curr.state in [ms_compiled_waitcrc,ms_compiled,ms_processed] then
  711. break;
  712. { add this unit to the dependencies }
  713. lu.adddependency(curr,frominterface);
  714. {$ENDIF}
  715. { check hints }
  716. pu.check_hints;
  717. end;
  718. pu:=tused_unit(pu.next);
  719. end;
  720. Restorestate;
  721. end;
  722. {
  723. Connect loaded units: check crc and add to symbol tables.
  724. this can only be called after all units were actually loaded!
  725. }
  726. procedure connect_loaded_units(_module : tmodule; preservest:tsymtable);
  727. var
  728. pu : tused_unit;
  729. sorg : ansistring;
  730. unitsymtable: tabstractunitsymtable;
  731. begin
  732. // writeln(_module.get_modulename,': Connecting units');
  733. pu:=tused_unit(_module.used_units.first);
  734. while assigned(pu) do
  735. begin
  736. {
  737. Writeln('Connect : ',Assigned(_module.modulename), ' ', assigned(pu.u), ' ' ,assigned(pu.u.modulename));
  738. if assigned(pu.u) then
  739. begin
  740. if assigned(pu.u.modulename) then
  741. Writeln(_module.modulename^,': Examining connect of file ',pu._fn,' (',pu.u.modulename^,')')
  742. else
  743. Writeln(_module.modulename^,': Examining connect of file ',pu._fn);
  744. end
  745. else
  746. Writeln(_module.modulename^,': Examining unit without module... ');
  747. }
  748. if not (pu.in_uses and
  749. (pu.in_interface=_module.in_interface)) then
  750. begin
  751. // writeln('Must not connect ',pu.u.modulename^,' (pu.in_interface: ',pu.in_interface,' <> module.in_interface',_module.in_interface,')');
  752. end
  753. else
  754. begin
  755. // writeln('Must connect ',pu.u.modulename^,'(sym: ',pu.unitsym.realname,')');
  756. { save crc values }
  757. pu.checksum:=pu.u.crc;
  758. pu.interface_checksum:=pu.u.interface_crc;
  759. pu.indirect_checksum:=pu.u.indirect_crc;
  760. if tppumodule(pu.u).nsprefix<>'' then
  761. begin
  762. { use the name as declared in the uses section for -Un }
  763. sorg:=tppumodule(pu.u).nsprefix+'.'+pu.unitsym.realname;
  764. { update unitsym now that we have access to the full name }
  765. pu.unitsym.free;
  766. pu.unitsym:=cunitsym.create(sorg,pu.u);
  767. end
  768. else
  769. begin
  770. { connect unitsym to the module }
  771. pu.unitsym.module:=pu.u;
  772. pu.unitsym.register_sym;
  773. end;
  774. {
  775. Add the unit symbol in the current symtable.
  776. localsymtable will be nil after the interface uses clause is parsed and the local symtable
  777. is moved to the global.
  778. }
  779. if assigned(_module.localsymtable) then
  780. unitsymtable:=tabstractunitsymtable(_module.localsymtable)
  781. else
  782. unitsymtable:=tabstractunitsymtable(_module.globalsymtable);
  783. // Writeln('Adding used unit sym ',pu.unitsym.realName,' to table ',unitsymtable.get_name);
  784. unitsymtable.insertunit(pu.unitsym);
  785. { add to symtable stack }
  786. // Writeln('Adding used unit symtable ',pu.u.globalsymtable.name^,' (',pu.u.globalsymtable.DefList.Count, ' defs) to stack');
  787. if assigned(preservest) then
  788. symtablestack.pushafter(pu.u.globalsymtable,preservest)
  789. else
  790. symtablestack.push(pu.u.globalsymtable);
  791. if (m_mac in current_settings.modeswitches) and
  792. assigned(pu.u.globalmacrosymtable) then
  793. macrosymtablestack.push(pu.u.globalmacrosymtable);
  794. end;
  795. pu:=tused_unit(pu.next);
  796. end;
  797. // writeln(_module.get_modulename,': Done Connecting units');
  798. end;
  799. procedure reset_all_defs(curr: tmodule);
  800. begin
  801. if assigned(curr.wpoinfo) then
  802. curr.wpoinfo.resetdefs;
  803. end;
  804. procedure free_localsymtables(st:TSymtable);
  805. var
  806. i : longint;
  807. def : tstoreddef;
  808. pd : tprocdef;
  809. begin
  810. for i:=0 to st.DefList.Count-1 do
  811. begin
  812. def:=tstoreddef(st.DefList[i]);
  813. if def.typ=procdef then
  814. begin
  815. pd:=tprocdef(def);
  816. if assigned(pd.localst) and
  817. (pd.localst.symtabletype<>staticsymtable) and
  818. not(po_inline in pd.procoptions) then
  819. begin
  820. free_localsymtables(pd.localst);
  821. pd.localst.free;
  822. pd.localst:=nil;
  823. end;
  824. pd.freeimplprocdefinfo;
  825. pd.done_paraloc_info(calleeside);
  826. end;
  827. end;
  828. end;
  829. procedure free_unregistered_localsymtable_elements(curr : tmodule);
  830. procedure remove_from_procdeflist(adef: tdef);
  831. var
  832. i: Integer;
  833. childdef: tdef;
  834. begin
  835. if adef=nil then exit;
  836. if (adef.typ in [objectdef, recorddef]) and (adef is tabstractrecorddef) then
  837. begin
  838. if tabstractrecorddef(adef).symtable<>nil then
  839. for i:=0 to tabstractrecorddef(adef).symtable.DefList.Count-1 do
  840. begin
  841. childdef:=tdef(tabstractrecorddef(adef).symtable.DefList[i]);
  842. remove_from_procdeflist(childdef);
  843. end;
  844. end
  845. else
  846. if adef.typ=procdef then
  847. begin
  848. tprocsym(tprocdef(adef).procsym).ProcdefList.Remove(adef);
  849. if tprocdef(adef).localst<>nil then
  850. for i:=0 to tprocdef(adef).localst.DefList.Count-1 do
  851. begin
  852. childdef:=tdef(tprocdef(adef).localst.DefList[i]);
  853. remove_from_procdeflist(childdef);
  854. end;
  855. end;
  856. end;
  857. var
  858. i: longint;
  859. def: tdef;
  860. sym: tsym;
  861. begin
  862. for i:=curr.localsymtable.deflist.count-1 downto 0 do
  863. begin
  864. def:=tdef(curr.localsymtable.deflist[i]);
  865. { since commit 48986 deflist might have NIL entries }
  866. if not assigned(def) then
  867. continue;
  868. { this also frees def, as the defs are owned by the symtable }
  869. if not def.is_registered and
  870. not(df_not_registered_no_free in def.defoptions) then
  871. begin
  872. { if it's a procdef, unregister it from its procsym first,
  873. unless that sym hasn't been registered either (it's possible
  874. to have one overload in the interface and another in the
  875. implementation) }
  876. remove_from_procdeflist(def);
  877. curr.localsymtable.deletedef(def);
  878. end;
  879. end;
  880. { from high to low so we hopefully have moves of less data }
  881. for i:=curr.localsymtable.symlist.count-1 downto 0 do
  882. begin
  883. sym:=tsym(curr.localsymtable.symlist[i]);
  884. { this also frees sym, as the symbols are owned by the symtable }
  885. if not sym.is_registered then
  886. curr.localsymtable.DeleteSym(sym);
  887. end;
  888. end;
  889. procedure setupglobalswitches;
  890. begin
  891. if (cs_create_pic in current_settings.moduleswitches) then
  892. begin
  893. def_system_macro('FPC_PIC');
  894. def_system_macro('PIC');
  895. end;
  896. end;
  897. function create_main_proc(const name:TSymStr;potype:tproctypeoption;st:TSymtable):tcgprocinfo;
  898. var
  899. ps : tprocsym;
  900. pd : tprocdef;
  901. begin
  902. { there should be no current_procinfo available }
  903. if assigned(current_procinfo) then
  904. internalerror(200304275);
  905. {Generate a procsym for main}
  906. ps:=cprocsym.create('$'+name);
  907. { always register the symbol }
  908. ps.register_sym;
  909. { main are always used }
  910. inc(ps.refs);
  911. st.insertsym(ps);
  912. pd:=tprocdef(cnodeutils.create_main_procdef(target_info.cprefix+name,potype,ps));
  913. { We don't need a local symtable, change it into the static symtable }
  914. if not (potype in [potype_mainstub,potype_pkgstub,potype_libmainstub]) then
  915. begin
  916. pd.localst.free;
  917. pd.localst:=st;
  918. end
  919. else if (potype=potype_pkgstub) and
  920. (target_info.system in systems_all_windows+systems_nativent) then
  921. pd.proccalloption:=pocall_stdcall
  922. else
  923. pd.proccalloption:=pocall_cdecl;
  924. handle_calling_convention(pd,hcc_default_actions_impl);
  925. { set procinfo and current_procinfo.procdef }
  926. result:=tcgprocinfo(cprocinfo.create(nil));
  927. result.procdef:=pd;
  928. { main proc does always a call e.g. to init system unit }
  929. if potype<>potype_pkgstub then
  930. include(result.flags,pi_do_call);
  931. end;
  932. procedure release_main_proc(curr: tmodule; pi:tcgprocinfo);
  933. begin
  934. { remove localst as it was replaced by staticsymtable }
  935. pi.procdef.localst:=nil;
  936. { remove procinfo }
  937. curr.procinfo:=nil;
  938. pi.free;
  939. pi:=nil;
  940. end;
  941. { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }
  942. procedure maybe_load_got(curr: tmodule);
  943. {$if defined(i386) or defined (sparcgen)}
  944. var
  945. gotvarsym : tstaticvarsym;
  946. {$endif i386 or sparcgen}
  947. begin
  948. {$if defined(i386) or defined(sparcgen)}
  949. if (cs_create_pic in current_settings.moduleswitches) and
  950. (tf_pic_uses_got in target_info.flags) then
  951. begin
  952. { insert symbol for got access in assembler code}
  953. gotvarsym:=cstaticvarsym.create('_GLOBAL_OFFSET_TABLE_',
  954. vs_value,voidpointertype,[vo_is_external]);
  955. gotvarsym.set_mangledname('_GLOBAL_OFFSET_TABLE_');
  956. curr.localsymtable.insertsym(gotvarsym);
  957. { avoid unnecessary warnings }
  958. gotvarsym.varstate:=vs_read;
  959. gotvarsym.refs:=1;
  960. end;
  961. {$endif i386 or sparcgen}
  962. end;
  963. function gen_implicit_initfinal(curr: tmodule; flag:tmoduleflag;st:TSymtable):tcgprocinfo;
  964. begin
  965. { create procdef }
  966. case flag of
  967. mf_init :
  968. begin
  969. result:=create_main_proc(make_mangledname('',curr.localsymtable,'init_implicit$'),potype_unitinit,st);
  970. result.procdef.aliasnames.concat(make_mangledname('INIT$',curr.localsymtable,''));
  971. end;
  972. mf_finalize :
  973. begin
  974. result:=create_main_proc(make_mangledname('',curr.localsymtable,'finalize_implicit$'),potype_unitfinalize,st);
  975. result.procdef.aliasnames.concat(make_mangledname('FINALIZE$',curr.localsymtable,''));
  976. if (not curr.is_unit) then
  977. result.procdef.aliasnames.concat('PASCALFINALIZE');
  978. end;
  979. else
  980. internalerror(200304253);
  981. end;
  982. result.code:=cnothingnode.create;
  983. end;
  984. procedure copy_macro(p:TObject; arg:pointer);
  985. begin
  986. TModule(arg).globalmacrosymtable.insertsym(tmacro(p).getcopy);
  987. end;
  988. function try_consume_hintdirective(var moduleopt:tmoduleoptions; var deprecatedmsg:pshortstring):boolean;
  989. var
  990. deprecated_seen,
  991. last_is_deprecated:boolean;
  992. begin
  993. try_consume_hintdirective:=false;
  994. deprecated_seen:=false;
  995. repeat
  996. last_is_deprecated:=false;
  997. case idtoken of
  998. _LIBRARY :
  999. begin
  1000. include(moduleopt,mo_hint_library);
  1001. try_consume_hintdirective:=true;
  1002. end;
  1003. _DEPRECATED :
  1004. begin
  1005. { allow deprecated only once }
  1006. if deprecated_seen then
  1007. break;
  1008. include(moduleopt,mo_hint_deprecated);
  1009. try_consume_hintdirective:=true;
  1010. last_is_deprecated:=true;
  1011. deprecated_seen:=true;
  1012. end;
  1013. _EXPERIMENTAL :
  1014. begin
  1015. include(moduleopt,mo_hint_experimental);
  1016. try_consume_hintdirective:=true;
  1017. end;
  1018. _PLATFORM :
  1019. begin
  1020. include(moduleopt,mo_hint_platform);
  1021. try_consume_hintdirective:=true;
  1022. end;
  1023. _UNIMPLEMENTED :
  1024. begin
  1025. include(moduleopt,mo_hint_unimplemented);
  1026. try_consume_hintdirective:=true;
  1027. end;
  1028. else
  1029. break;
  1030. end;
  1031. consume(Token);
  1032. { handle deprecated message }
  1033. if ((token=_CSTRING) or (token=_CCHAR)) and last_is_deprecated then
  1034. begin
  1035. if deprecatedmsg<>nil then
  1036. internalerror(201001221);
  1037. if token=_CSTRING then
  1038. deprecatedmsg:=stringdup(current_scanner.cstringpattern)
  1039. else
  1040. deprecatedmsg:=stringdup(current_scanner.pattern);
  1041. consume(token);
  1042. include(moduleopt,mo_has_deprecated_msg);
  1043. end;
  1044. until false;
  1045. end;
  1046. {$ifdef jvm}
  1047. procedure addmoduleclass(curr : tmodule);
  1048. var
  1049. def: tobjectdef;
  1050. typesym: ttypesym;
  1051. begin
  1052. { java_jlobject may not have been parsed yet (system unit); in any
  1053. case, we only use this to refer to the class type, so inheritance
  1054. does not matter }
  1055. def:=cobjectdef.create(odt_javaclass,'__FPC_JVM_Module_Class_Alias$',nil,true);
  1056. include(def.objectoptions,oo_is_external);
  1057. include(def.objectoptions,oo_is_sealed);
  1058. def.objextname:=stringdup(curr.realmodulename^);
  1059. typesym:=ctypesym.create('__FPC_JVM_Module_Class_Alias$',def);
  1060. symtablestack.top.insertsym(typesym);
  1061. end;
  1062. {$endif jvm}
  1063. type
  1064. tfinishstate=record
  1065. init_procinfo:tcgprocinfo;
  1066. finalize_procinfo:tcgprocinfo;
  1067. end;
  1068. pfinishstate=^tfinishstate;
  1069. function proc_unit_implementation(curr: tmodule):boolean;
  1070. var
  1071. init_procinfo,
  1072. finalize_procinfo : tcgprocinfo;
  1073. i,j : integer;
  1074. finishstate:pfinishstate;
  1075. begin
  1076. result:=true;
  1077. init_procinfo:=nil;
  1078. finalize_procinfo:=nil;
  1079. finishstate:=nil;
  1080. set_current_module(curr);
  1081. { We get here only after used modules were loaded }
  1082. connect_loaded_units(curr,curr.globalsymtable);
  1083. { All units are read, now give them a number }
  1084. curr.updatemaps;
  1085. { Consume the semicolon if needed.
  1086. At this point the units in the uses clause have at least been parsed
  1087. and are connected, and conditional compilation expressions can
  1088. use the symbols from those units }
  1089. if curr.consume_semicolon_after_uses then
  1090. begin
  1091. consume(_SEMICOLON);
  1092. curr.consume_semicolon_after_uses:=false;
  1093. end;
  1094. { further, changing the globalsymtable is not allowed anymore }
  1095. curr.globalsymtable.sealed:=true;
  1096. symtablestack.push(curr.localsymtable);
  1097. if not curr.interface_only then
  1098. begin
  1099. Message1(parser_u_parsing_implementation,curr.modulename^);
  1100. if curr.in_interface then
  1101. internalerror(200212285);
  1102. { Compile the unit }
  1103. init_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'init$'),potype_unitinit,curr.localsymtable);
  1104. init_procinfo.procdef.aliasnames.concat(make_mangledname('INIT$',curr.localsymtable,''));
  1105. init_procinfo.parse_body;
  1106. { save file pos for debuginfo }
  1107. curr.mainfilepos:=init_procinfo.entrypos;
  1108. { parse finalization section }
  1109. if token=_FINALIZATION then
  1110. begin
  1111. { Compile the finalize }
  1112. finalize_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'finalize$'),potype_unitfinalize,curr.localsymtable);
  1113. finalize_procinfo.procdef.aliasnames.concat(make_mangledname('FINALIZE$',curr.localsymtable,''));
  1114. finalize_procinfo.parse_body;
  1115. end
  1116. end;
  1117. { remove all units that we are waiting for that are already waiting for
  1118. us => breaking up circles }
  1119. for i:=0 to curr.waitingunits.count-1 do
  1120. for j:=curr.waitingforunit.count-1 downto 0 do
  1121. if curr.waitingunits[i]=curr.waitingforunit[j] then
  1122. curr.waitingforunit.Delete(j);
  1123. {$ifdef DEBUG_UNITWAITING}
  1124. Writeln('Unit ', curr.modulename^, ' is waiting for units: ');
  1125. for i:=curr.waitingforunit.count-1 downto 0 do
  1126. writeln(' ',i,'/',curr.waitingforunit.count,' ',tmodule(curr.waitingforunit[i]).realmodulename^);
  1127. {$endif}
  1128. result:=curr.waitingforunit.count=0;
  1129. { save all information that is needed for finishing the unit }
  1130. New(finishstate);
  1131. finishstate^.init_procinfo:=init_procinfo;
  1132. finishstate^.finalize_procinfo:=finalize_procinfo;
  1133. curr.finishstate:=finishstate;
  1134. if result then
  1135. result:=finish_compile_unit(curr)
  1136. else
  1137. curr.state:=ms_compiling_waitfinish;
  1138. end;
  1139. function parse_unit_interface_declarations(curr : tmodule) : boolean;
  1140. begin
  1141. result:=true;
  1142. set_current_module(curr);
  1143. { update the symtable }
  1144. connect_loaded_units(curr,nil);
  1145. { We must do this again, because units can have been added to the list while another task was being handled }
  1146. curr.updatemaps;
  1147. { consume the semicolon after maps have been updated else conditional compiling expressions
  1148. might cause internal errors, see tw8611 }
  1149. if curr.consume_semicolon_after_uses then
  1150. begin
  1151. consume(_SEMICOLON);
  1152. curr.consume_semicolon_after_uses:=false;
  1153. end;
  1154. { now push our own symtable }
  1155. symtablestack.push(curr.globalsymtable);
  1156. { Dump stack
  1157. Write(curr.modulename^);
  1158. symtablestack.dump;
  1159. }
  1160. { ... parse the declarations }
  1161. Message1(parser_u_parsing_interface,curr.realmodulename^);
  1162. {$ifdef jvm}
  1163. { fake classdef to represent the class corresponding to the unit }
  1164. addmoduleclass(curr);
  1165. {$endif}
  1166. read_interface_declarations;
  1167. { Export macros defined in the interface for macpas. The macros
  1168. are put in the globalmacrosymtable that will only be used by other
  1169. units. The current unit continues to use the localmacrosymtable }
  1170. if (m_mac in current_settings.modeswitches) then
  1171. begin
  1172. curr.globalmacrosymtable:=tmacrosymtable.create(true);
  1173. curr.localmacrosymtable.SymList.ForEachCall(@copy_macro,curr);
  1174. end;
  1175. { leave when we got an error }
  1176. if (Errorcount>0) and not status.skip_error then
  1177. begin
  1178. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1179. status.skip_error:=true;
  1180. symtablestack.pop(curr.globalsymtable);
  1181. {$ifdef DEBUG_NODE_XML}
  1182. XMLFinalizeNodeFile('unit');
  1183. {$endif DEBUG_NODE_XML}
  1184. exit;
  1185. end;
  1186. { we need to be able to reference these in descendants,
  1187. so they must be generated and included in the interface }
  1188. if (target_cpu=tsystemcpu.cpu_wasm32) then
  1189. add_synthetic_interface_classes_for_st(curr.globalsymtable,true,false);
  1190. { Our interface is compiled, generate interface CRC and switch to implementation }
  1191. {$IFDEF Debug_WaitCRC}
  1192. writeln('parse_unit_interface_declarations ',curr.realmodulename^);
  1193. {$ENDIF}
  1194. if not(cs_compilesystem in current_settings.moduleswitches) and
  1195. (Errorcount=0) then
  1196. tppumodule(curr).getppucrc;
  1197. curr.in_interface:=false;
  1198. curr.interface_compiled:=true;
  1199. {$IFDEF EnableCTaskPPU}
  1200. {$ELSE}
  1201. { First reload all units depending on our interface, we need to do this
  1202. in the implementation part to prevent erroneous circular references }
  1203. tppumodule(curr).setdefgeneration;
  1204. tppumodule(curr).reload_flagged_units;
  1205. {$ENDIF}
  1206. { Parse the implementation section }
  1207. if (m_mac in current_settings.modeswitches) and try_to_consume(_END) then
  1208. curr.interface_only:=true
  1209. else
  1210. curr.interface_only:=false;
  1211. parse_only:=false;
  1212. { create static symbol table }
  1213. curr.localsymtable:=tstaticsymtable.create(curr.realmodulename^,curr.moduleid);
  1214. { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }
  1215. maybe_load_got(curr);
  1216. if not curr.interface_only then
  1217. begin
  1218. consume(_IMPLEMENTATION);
  1219. Message1(unit_u_loading_implementation_units,curr.modulename^);
  1220. { Read the implementation units }
  1221. if token=_USES then
  1222. begin
  1223. parseusesclause(curr);
  1224. if not loadunits(curr,false) then
  1225. curr.state:=ms_compiling_waitimpl;
  1226. { do not consume the semicolon yet, because the units in the uses clause
  1227. may not yet be loaded and conditional compilation expressions may
  1228. depend on symbols from those units }
  1229. curr.consume_semicolon_after_uses:=True;
  1230. end
  1231. else
  1232. curr.consume_semicolon_after_uses:=False;
  1233. end;
  1234. if curr.state in [ms_compiled,ms_processed] then
  1235. begin
  1236. // Writeln('Popping global symtable ?');
  1237. symtablestack.pop(curr.globalsymtable);
  1238. end;
  1239. { Can we continue compiling ? }
  1240. result:=curr.state<>ms_compiling_waitimpl;
  1241. if result then
  1242. result:=proc_unit_implementation(curr);
  1243. end;
  1244. function proc_unit(curr: tmodule):boolean;
  1245. var
  1246. main_file: tinputfile;
  1247. s1,s2 : ^string; {Saves stack space}
  1248. unitname : ansistring;
  1249. unitname8 : string[8];
  1250. feature : tfeature;
  1251. load_ok : boolean;
  1252. begin
  1253. result:=true;
  1254. if m_mac in current_settings.modeswitches then
  1255. curr.mode_switch_allowed:= false;
  1256. consume(_UNIT);
  1257. if curr.is_initial then
  1258. Status.IsExe:=false;
  1259. unitname:=current_scanner.orgpattern;
  1260. consume(_ID);
  1261. while token=_POINT do
  1262. begin
  1263. consume(_POINT);
  1264. unitname:=unitname+'.'+current_scanner.orgpattern;
  1265. consume(_ID);
  1266. end;
  1267. { create filenames and unit name }
  1268. main_file := current_scanner.inputfile;
  1269. while assigned(main_file.next) do
  1270. main_file := main_file.next;
  1271. new(s1);
  1272. s1^:=curr.modulename^;
  1273. curr.SetFileName(main_file.path+main_file.name,true);
  1274. curr.SetModuleName(unitname);
  1275. {$ifdef DEBUG_NODE_XML}
  1276. XMLInitializeNodeFile('unit', unitname);
  1277. {$endif DEBUG_NODE_XML}
  1278. { check for system unit }
  1279. new(s2);
  1280. s2^:=upper(ChangeFileExt(ExtractFileName(main_file.name),''));
  1281. unitname8:=copy(curr.modulename^,1,8);
  1282. if (cs_check_unit_name in current_settings.globalswitches) and
  1283. (
  1284. not(
  1285. (curr.modulename^=s2^) or
  1286. (
  1287. (length(curr.modulename^)>8) and
  1288. (unitname8=s2^)
  1289. )
  1290. )
  1291. or
  1292. (
  1293. (length(s1^)>8) and
  1294. (s1^<>curr.modulename^)
  1295. )
  1296. ) then
  1297. Message2(unit_e_illegal_unit_name,curr.realmodulename^,s1^);
  1298. if (curr.modulename^='SYSTEM') then
  1299. include(current_settings.moduleswitches,cs_compilesystem);
  1300. dispose(s2);
  1301. dispose(s1);
  1302. if (target_info.system in systems_unit_program_exports) then
  1303. exportlib.preparelib(curr.realmodulename^);
  1304. { parse hint directives }
  1305. try_consume_hintdirective(curr.moduleoptions, curr.deprecatedmsg);
  1306. consume(_SEMICOLON);
  1307. { handle the global switches, do this before interface, because after interface has been
  1308. read, all following directives are parsed as well }
  1309. setupglobalswitches;
  1310. { generate now the global symboltable,
  1311. define first as local to overcome dependency conflicts }
  1312. curr.localsymtable:=tglobalsymtable.create(curr.modulename^,curr.moduleid);
  1313. { insert unitsym of this unit to prevent other units having
  1314. the same name }
  1315. tabstractunitsymtable(curr.localsymtable).insertunit(cunitsym.create(curr.realmodulename^,curr));
  1316. { load default system unit, it must be loaded before interface is parsed
  1317. else we cannot use e.g. feature switches before the next real token }
  1318. load_ok:=loadsystemunit(curr);
  1319. { system unit is loaded, now insert feature defines }
  1320. for feature:=low(tfeature) to high(tfeature) do
  1321. if feature in features then
  1322. def_system_macro('FPC_HAS_FEATURE_'+featurestr[feature]);
  1323. consume(_INTERFACE);
  1324. { global switches are read, so further changes aren't allowed }
  1325. curr.in_global:=false;
  1326. message1(unit_u_loading_interface_units,curr.modulename^);
  1327. { update status }
  1328. status.currentmodule:=curr.realmodulename^;
  1329. { maybe turn off m_objpas if we are compiling objpas }
  1330. if (curr.modulename^='OBJPAS') then
  1331. exclude(current_settings.modeswitches,m_objpas);
  1332. { maybe turn off m_mac if we are compiling macpas }
  1333. if (curr.modulename^='MACPAS') then
  1334. exclude(current_settings.modeswitches,m_mac);
  1335. parse_only:=true;
  1336. { load default units, like language mode units }
  1337. if not(cs_compilesystem in current_settings.moduleswitches) then
  1338. load_ok:=loaddefaultunits(curr) and load_ok;
  1339. { insert qualifier for the system unit (allows system.writeln) }
  1340. if not(cs_compilesystem in current_settings.moduleswitches) and
  1341. (token=_USES) then
  1342. begin
  1343. // We do this as late as possible.
  1344. if Assigned(curr) then
  1345. curr.Loadlocalnamespacelist
  1346. else
  1347. current_namespacelist:=Nil;
  1348. parseusesclause(curr);
  1349. load_ok:=loadunits(curr,true) and load_ok;
  1350. { has it been compiled at a higher level ?}
  1351. if curr.state in [ms_compiled,ms_processed] then
  1352. begin
  1353. Message1(parser_u_already_compiled,curr.realmodulename^);
  1354. exit;
  1355. end;
  1356. curr.consume_semicolon_after_uses:=true;
  1357. end
  1358. else
  1359. curr.consume_semicolon_after_uses:=false;
  1360. { move the global symtable from the temporary local to global }
  1361. current_module.globalsymtable:=current_module.localsymtable;
  1362. current_module.localsymtable:=nil;
  1363. { Now we check if we can continue. }
  1364. if not load_ok then
  1365. curr.state:=ms_compiling_waitintf;
  1366. { create whole program optimisation information (may already be
  1367. updated in the interface, e.g., in case of classrefdef typed
  1368. constants }
  1369. curr.wpoinfo:=tunitwpoinfo.create;
  1370. { Can we continue compiling ? }
  1371. result:=curr.state<>ms_compiling_waitintf;
  1372. if result then
  1373. result:=parse_unit_interface_declarations(curr);
  1374. end;
  1375. procedure module_is_done(curr: tmodule);inline;
  1376. begin
  1377. dispose(pfinishstate(curr.finishstate));
  1378. curr.finishstate:=nil;
  1379. end;
  1380. function finish_compile_unit(module: tmodule): boolean;
  1381. function is_assembler_generated:boolean;
  1382. var
  1383. hal : tasmlisttype;
  1384. begin
  1385. result:=false;
  1386. if Errorcount=0 then
  1387. begin
  1388. for hal:=low(TasmlistType) to high(TasmlistType) do
  1389. if not current_asmdata.asmlists[hal].empty then
  1390. begin
  1391. result:=true;
  1392. exit;
  1393. end;
  1394. end;
  1395. end;
  1396. var
  1397. {$ifdef EXTDEBUG}
  1398. store_crc,
  1399. {$endif EXTDEBUG}
  1400. force_init_final : boolean;
  1401. init_procinfo,
  1402. finalize_procinfo : tcgprocinfo;
  1403. i : longint;
  1404. ag : boolean;
  1405. finishstate : tfinishstate;
  1406. waitingmodule : tmodule;
  1407. begin
  1408. result:=true;
  1409. { curr is now module }
  1410. if not assigned(module.finishstate) then
  1411. internalerror(2012091801);
  1412. finishstate:=pfinishstate(module.finishstate)^;
  1413. finalize_procinfo:=finishstate.finalize_procinfo;
  1414. init_procinfo:=finishstate.init_procinfo;
  1415. { Generate specializations of objectdefs methods }
  1416. generate_specialization_procs;
  1417. // This needs to be done before we generate the VMTs
  1418. if (target_cpu=tsystemcpu.cpu_wasm32) then
  1419. begin
  1420. add_synthetic_interface_classes_for_st(module.globalsymtable,false,true);
  1421. add_synthetic_interface_classes_for_st(module.localsymtable,true,true);
  1422. end;
  1423. { generate construction functions for all attributes in the unit:
  1424. this must be done before writing the VMTs because
  1425. during VMT writing the extended field info is written }
  1426. generate_attr_constrs(current_module.used_rtti_attrs);
  1427. { Generate VMTs }
  1428. if Errorcount=0 then
  1429. begin
  1430. write_vmts(module.globalsymtable,true);
  1431. write_vmts(module.localsymtable,false);
  1432. end;
  1433. { add implementations for synthetic method declarations added by
  1434. the compiler }
  1435. add_synthetic_method_implementations(module.globalsymtable);
  1436. add_synthetic_method_implementations(module.localsymtable);
  1437. { if the unit contains ansi/widestrings, initialization and
  1438. finalization code must be forced }
  1439. force_init_final:=tglobalsymtable(module.globalsymtable).needs_init_final or
  1440. tstaticsymtable(module.localsymtable).needs_init_final;
  1441. { should we force unit initialization? }
  1442. { this is a hack, but how can it be done better ? }
  1443. { Now the sole purpose of this is to change 'init' to 'init_implicit',
  1444. is it needed at all? (Sergei) }
  1445. { it's needed in case cnodeutils.force_init = true }
  1446. if (force_init_final or cnodeutils.force_init) and
  1447. (
  1448. not assigned(init_procinfo) or
  1449. has_no_code(init_procinfo.code)
  1450. ) then
  1451. begin
  1452. { first release the not used init procinfo }
  1453. if assigned(init_procinfo) then
  1454. begin
  1455. release_proc_symbol(init_procinfo.procdef);
  1456. release_main_proc(module,init_procinfo);
  1457. end;
  1458. init_procinfo:=gen_implicit_initfinal(module,mf_init,module.localsymtable);
  1459. end;
  1460. if (force_init_final or cnodeutils.force_final) and
  1461. (
  1462. not assigned(finalize_procinfo) or
  1463. has_no_code(finalize_procinfo.code)
  1464. ) then
  1465. begin
  1466. { first release the not used finalize procinfo }
  1467. if assigned(finalize_procinfo) then
  1468. begin
  1469. release_proc_symbol(finalize_procinfo.procdef);
  1470. release_main_proc(module,finalize_procinfo);
  1471. end;
  1472. finalize_procinfo:=gen_implicit_initfinal(module,mf_finalize,module.localsymtable);
  1473. end;
  1474. { Now both init and finalize bodies are read and it is known
  1475. which variables are used in both init and finalize we can now
  1476. generate the code. This is required to prevent putting a variable in
  1477. a register that is also used in the finalize body (PFV) }
  1478. if assigned(init_procinfo) then
  1479. begin
  1480. if (force_init_final or cnodeutils.force_init) or
  1481. not(has_no_code(init_procinfo.code)) then
  1482. begin
  1483. init_procinfo.code:=cnodeutils.wrap_proc_body(init_procinfo.procdef,init_procinfo.code);
  1484. init_procinfo.generate_code_tree;
  1485. include(module.moduleflags,mf_init);
  1486. end
  1487. else
  1488. release_proc_symbol(init_procinfo.procdef);
  1489. init_procinfo.resetprocdef;
  1490. release_main_proc(module,init_procinfo);
  1491. end;
  1492. if assigned(finalize_procinfo) then
  1493. begin
  1494. if force_init_final or
  1495. cnodeutils.force_init or
  1496. not(has_no_code(finalize_procinfo.code)) then
  1497. begin
  1498. finalize_procinfo.code:=cnodeutils.wrap_proc_body(finalize_procinfo.procdef,finalize_procinfo.code);
  1499. finalize_procinfo.generate_code_tree;
  1500. include(module.moduleflags,mf_finalize);
  1501. end
  1502. else
  1503. release_proc_symbol(finalize_procinfo.procdef);
  1504. finalize_procinfo.resetprocdef;
  1505. release_main_proc(module,finalize_procinfo);
  1506. end;
  1507. symtablestack.pop(module.localsymtable);
  1508. symtablestack.pop(module.globalsymtable);
  1509. { the last char should always be a point }
  1510. { Do not attempt to read next token after dot,
  1511. there may be a #0 when the unit was finished in a separate stage }
  1512. consume_last_dot;
  1513. { reset wpo flags for all defs }
  1514. reset_all_defs(module);
  1515. if (Errorcount=0) then
  1516. begin
  1517. { tests, if all (interface) forwards are resolved }
  1518. tstoredsymtable(module.globalsymtable).check_forwards;
  1519. { check if all private fields are used }
  1520. tstoredsymtable(module.globalsymtable).allprivatesused;
  1521. { test static symtable }
  1522. tstoredsymtable(module.localsymtable).allsymbolsused;
  1523. tstoredsymtable(module.localsymtable).allprivatesused;
  1524. tstoredsymtable(module.localsymtable).check_forwards;
  1525. tstoredsymtable(module.localsymtable).checklabels;
  1526. { used units }
  1527. module.allunitsused;
  1528. end;
  1529. { leave when we got an error }
  1530. if (Errorcount>0) and not status.skip_error then
  1531. begin
  1532. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1533. status.skip_error:=true;
  1534. module_is_done(module);
  1535. {$ifdef DEBUG_NODE_XML}
  1536. XMLFinalizeNodeFile('unit');
  1537. {$endif DEBUG_NODE_XML}
  1538. exit;
  1539. end;
  1540. { if an Objective-C module, generate rtti and module info }
  1541. MaybeGenerateObjectiveCImageInfo(module.globalsymtable,module.localsymtable);
  1542. { do we need to add the variants unit? }
  1543. maybeloadvariantsunit(module);
  1544. { generate rtti/init tables }
  1545. write_persistent_type_info(module.globalsymtable,true);
  1546. write_persistent_type_info(module.localsymtable,false);
  1547. { Tables }
  1548. cnodeutils.InsertThreadvars;
  1549. { Resource strings }
  1550. GenerateResourceStrings;
  1551. { Widestring typed constants }
  1552. cnodeutils.InsertWideInits;
  1553. { Resourcestring references }
  1554. cnodeutils.InsertResStrInits;
  1555. { generate debuginfo }
  1556. if (cs_debuginfo in current_settings.moduleswitches) then
  1557. current_debuginfo.inserttypeinfo;
  1558. { generate imports }
  1559. if module.ImportLibraryList.Count>0 then
  1560. importlib.generatelib;
  1561. { insert own objectfile, or say that it's in a library
  1562. (no check for an .o when loading) }
  1563. ag:=is_assembler_generated;
  1564. if ag then
  1565. insertobjectfile(module)
  1566. else
  1567. begin
  1568. module.headerflags:=module.headerflags or uf_no_link;
  1569. exclude(module.moduleflags,mf_has_stabs_debuginfo);
  1570. exclude(module.moduleflags,mf_has_dwarf_debuginfo);
  1571. end;
  1572. if ag then
  1573. begin
  1574. { create callframe info }
  1575. create_dwarf_frame;
  1576. { assemble }
  1577. create_objectfile(module);
  1578. end;
  1579. // remove all waits for this unit
  1580. for i:=0 to module.waitingunits.count-1 do
  1581. begin
  1582. waitingmodule:=tmodule(module.waitingunits[i]);
  1583. waitingmodule.remove_from_waitingforunits(module);
  1584. end;
  1585. // compute CRC
  1586. if ErrorCount=0 then
  1587. begin
  1588. if not module.usedunitsfinalcrc(waitingmodule) then
  1589. begin
  1590. { Some used units are still compiling, so their CRCs can change.
  1591. Compute the final CRC of this module, for the case of a
  1592. circular dependency, and wait.
  1593. }
  1594. {$IF defined(Debug_WaitCRC) or defined(Debug_FreeParseMem)}
  1595. writeln('finish_compile_unit ',module.realmodulename^,' waiting for used unit CRCs...');
  1596. {$ENDIF}
  1597. tppumodule(module).getppucrc;
  1598. module.crc_final:=true;
  1599. module.state:=ms_compiled_waitcrc;
  1600. exit(false);
  1601. end;
  1602. end;
  1603. result:=finish_unit(module);
  1604. end;
  1605. function finish_unit(module: tmodule): boolean;
  1606. var
  1607. {$ifdef EXTDEBUG}
  1608. store_crc,
  1609. {$endif EXTDEBUG}
  1610. store_interface_crc,
  1611. store_indirect_crc : cardinal;
  1612. i : longint;
  1613. waitingmodule : tmodule;
  1614. hstatus : TFPCHeapStatus;
  1615. begin
  1616. {$IF defined(Debug_WaitCRC) or defined(Debug_FreeParseMem)}
  1617. writeln('finish_unit ',module.realmodulename^,' write ppu and free mem...');
  1618. {$ENDIF}
  1619. result:=true;
  1620. { Write out the ppufile after the object file has been created }
  1621. store_interface_crc:=module.interface_crc;
  1622. store_indirect_crc:=module.indirect_crc;
  1623. {$ifdef EXTDEBUG}
  1624. store_crc:=module.crc;
  1625. {$endif EXTDEBUG}
  1626. if ErrorCount=0 then
  1627. tppumodule(module).writeppu;
  1628. if not(cs_compilesystem in current_settings.moduleswitches) then
  1629. begin
  1630. if store_interface_crc<>module.interface_crc then
  1631. Message1(unit_u_interface_crc_changed,module.ppufilename);
  1632. if store_indirect_crc<>module.indirect_crc then
  1633. Message1(unit_u_indirect_crc_changed,module.ppufilename);
  1634. end;
  1635. {$ifdef EXTDEBUG}
  1636. if not(cs_compilesystem in current_settings.moduleswitches) then
  1637. if (store_crc<>module.crc) then
  1638. Message1(unit_u_implementation_crc_changed,module.ppufilename);
  1639. {$endif EXTDEBUG}
  1640. { release unregistered defs/syms from the localsymtable }
  1641. free_unregistered_localsymtable_elements(module);
  1642. { release local symtables that are not needed anymore }
  1643. free_localsymtables(module.globalsymtable);
  1644. free_localsymtables(module.localsymtable);
  1645. { leave when we got an error }
  1646. if (Errorcount>0) and not status.skip_error then
  1647. begin
  1648. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1649. status.skip_error:=true;
  1650. module_is_done(module);
  1651. {$ifdef DEBUG_NODE_XML}
  1652. XMLFinalizeNodeFile('unit');
  1653. {$endif DEBUG_NODE_XML}
  1654. exit;
  1655. end;
  1656. {$ifdef debug_devirt}
  1657. { print out all instantiated class/object types }
  1658. writeln('constructed object/class/classreftypes in ',module.realmodulename^);
  1659. for i := 0 to module.wpoinfo.createdobjtypes.count-1 do
  1660. begin
  1661. write(' ',tdef(module.wpoinfo.createdobjtypes[i]).GetTypeName);
  1662. case tdef(module.wpoinfo.createdobjtypes[i]).typ of
  1663. objectdef:
  1664. case tobjectdef(module.wpoinfo.createdobjtypes[i]).objecttype of
  1665. odt_object:
  1666. writeln(' (object)');
  1667. odt_class:
  1668. writeln(' (class)');
  1669. else
  1670. internalerror(2008101103);
  1671. end;
  1672. else
  1673. internalerror(2008101104);
  1674. end;
  1675. end;
  1676. for i := 0 to module.wpoinfo.createdclassrefobjtypes.count-1 do
  1677. begin
  1678. write(' Class Of ',tdef(module.wpoinfo.createdclassrefobjtypes[i]).GetTypeName);
  1679. case tdef(module.wpoinfo.createdclassrefobjtypes[i]).typ of
  1680. objectdef:
  1681. case tobjectdef(module.wpoinfo.createdclassrefobjtypes[i]).objecttype of
  1682. odt_class:
  1683. writeln(' (classrefdef)');
  1684. else
  1685. internalerror(2008101105);
  1686. end
  1687. else
  1688. internalerror(2008101102);
  1689. end;
  1690. end;
  1691. {$endif debug_devirt}
  1692. Message1(unit_u_finished_compiling,module.modulename^);
  1693. module_is_done(module);
  1694. module.end_of_parsing;
  1695. {$ifdef DEBUG_NODE_XML}
  1696. XMLFinalizeNodeFile('unit');
  1697. {$endif DEBUG_NODE_XML}
  1698. if ((status.verbosity and V_Status)<>0) then
  1699. begin
  1700. {$IF defined(Debug_FreeParseMem)}
  1701. writeln('finish_unit ',module.realmodulename^,' wrote ppu and freed mem.');
  1702. {$ENDIF}
  1703. hstatus:=GetFPCHeapStatus;
  1704. WriteLn(DStr(hstatus.CurrHeapUsed shr 10),'/',DStr(hstatus.CurrHeapSize shr 10),' Kb Used');
  1705. end;
  1706. end;
  1707. function proc_package(curr: tmodule) : boolean;
  1708. var
  1709. main_file : tinputfile;
  1710. hp,hp2 : tmodule;
  1711. pkg : tpcppackage;
  1712. main_procinfo : tcgprocinfo;
  1713. force_init_final : boolean;
  1714. uu : tused_unit;
  1715. module_name: ansistring;
  1716. pentry: ppackageentry;
  1717. feature : tfeature;
  1718. begin
  1719. Result:=True;
  1720. Status.IsPackage:=true;
  1721. Status.IsExe:=true;
  1722. parse_only:=false;
  1723. main_procinfo:=nil;
  1724. {init_procinfo:=nil;
  1725. finalize_procinfo:=nil;}
  1726. if not (tf_supports_packages in target_info.flags) then
  1727. message1(parser_e_packages_not_supported,target_info.name);
  1728. if not RelocSectionSetExplicitly then
  1729. RelocSection:=true;
  1730. { Relocation works only without stabs under Windows when }
  1731. { external linker (LD) is used. LD generates relocs for }
  1732. { stab sections which is not loaded in memory. It causes }
  1733. { AV error when DLL is loaded and relocation is needed. }
  1734. { Internal linker does not have this problem. }
  1735. if RelocSection and
  1736. (target_info.system in systems_all_windows+[system_i386_wdosx]) and
  1737. (cs_link_extern in current_settings.globalswitches) then
  1738. begin
  1739. include(current_settings.globalswitches,cs_link_strip);
  1740. { Warning stabs info does not work with reloc section !! }
  1741. if (cs_debuginfo in current_settings.moduleswitches) and
  1742. (target_dbg.id=dbg_stabs) then
  1743. begin
  1744. Message1(parser_w_parser_reloc_no_debug,curr.mainsource);
  1745. Message(parser_w_parser_win32_debug_needs_WN);
  1746. exclude(current_settings.moduleswitches,cs_debuginfo);
  1747. end;
  1748. end;
  1749. { get correct output names }
  1750. main_file := current_scanner.inputfile;
  1751. while assigned(main_file.next) do
  1752. main_file := main_file.next;
  1753. curr.SetFileName(main_file.path+main_file.name,true);
  1754. { consume _PACKAGE word }
  1755. consume(_ID);
  1756. module_name:=current_scanner.orgpattern;
  1757. consume(_ID);
  1758. while token=_POINT do
  1759. begin
  1760. consume(_POINT);
  1761. module_name:=module_name+'.'+current_scanner.orgpattern;
  1762. consume(_ID);
  1763. end;
  1764. curr.setmodulename(module_name);
  1765. curr.ispackage:=true;
  1766. exportlib.preparelib(module_name);
  1767. pkg:=tpcppackage.create(module_name);
  1768. if tf_library_needs_pic in target_info.flags then
  1769. include(current_settings.moduleswitches,cs_create_pic);
  1770. { setup things using the switches, do this before the semicolon, because after the semicolon has been
  1771. read, all following directives are parsed as well }
  1772. setupglobalswitches;
  1773. {$ifdef DEBUG_NODE_XML}
  1774. XMLInitializeNodeFile('package', module_name);
  1775. {$endif DEBUG_NODE_XML}
  1776. consume(_SEMICOLON);
  1777. { global switches are read, so further changes aren't allowed }
  1778. curr.in_global:=false;
  1779. { set implementation flag }
  1780. curr.in_interface:=false;
  1781. curr.interface_compiled:=true;
  1782. { insert after the unit symbol tables the static symbol table }
  1783. { of the program }
  1784. curr.localsymtable:=tstaticsymtable.create(curr.realmodulename^,curr.moduleid);
  1785. { ensure that no packages are picked up from the options }
  1786. packagelist.clear;
  1787. // There should always be a requires, except for the system package. So we load here
  1788. if Assigned(curr) then
  1789. curr.Loadlocalnamespacelist
  1790. else
  1791. current_namespacelist:=Nil;
  1792. {Read the packages used by the package we compile.}
  1793. if (token=_ID) and (idtoken=_REQUIRES) then
  1794. begin
  1795. { consume _REQUIRES word }
  1796. consume(_ID);
  1797. while true do
  1798. begin
  1799. if token=_ID then
  1800. begin
  1801. module_name:=current_scanner.orgpattern;
  1802. consume(_ID);
  1803. while token=_POINT do
  1804. begin
  1805. consume(_POINT);
  1806. module_name:=module_name+'.'+current_scanner.orgpattern;
  1807. consume(_ID);
  1808. end;
  1809. add_package(module_name,false,true);
  1810. end
  1811. else
  1812. consume(_ID);
  1813. if token=_COMMA then
  1814. consume(_COMMA)
  1815. else
  1816. break;
  1817. end;
  1818. consume(_SEMICOLON);
  1819. end;
  1820. { now load all packages, so that we can determine whether a unit is
  1821. already provided by one of the loaded packages }
  1822. load_packages;
  1823. if packagelist.Count>0 then
  1824. begin
  1825. { this means the SYSTEM unit *must* be part of one of the required
  1826. packages, so load it }
  1827. AddUnit(curr,'system',false);
  1828. systemunit:=tglobalsymtable(symtablestack.top);
  1829. load_intern_types;
  1830. { system unit is loaded, now insert feature defines }
  1831. for feature:=low(tfeature) to high(tfeature) do
  1832. if feature in features then
  1833. def_system_macro('FPC_HAS_FEATURE_'+featurestr[feature]);
  1834. end;
  1835. {Load the units used by the program we compile.}
  1836. if (token=_ID) and (idtoken=_CONTAINS) then
  1837. begin
  1838. { consume _CONTAINS word }
  1839. consume(_ID);
  1840. while true do
  1841. begin
  1842. if token=_ID then
  1843. begin
  1844. module_name:=current_scanner.orgpattern;
  1845. consume(_ID);
  1846. while token=_POINT do
  1847. begin
  1848. consume(_POINT);
  1849. module_name:=module_name+'.'+current_scanner.orgpattern;
  1850. consume(_ID);
  1851. end;
  1852. hp:=AddUnit(curr,module_name);
  1853. if (hp.modulename^='SYSTEM') and not assigned(systemunit) then
  1854. begin
  1855. systemunit:=tglobalsymtable(hp.globalsymtable);
  1856. load_intern_types;
  1857. end;
  1858. end
  1859. else
  1860. consume(_ID);
  1861. if token=_COMMA then
  1862. consume(_COMMA)
  1863. else break;
  1864. end;
  1865. consume(_SEMICOLON);
  1866. end;
  1867. { All units are read, now give them a number }
  1868. curr.updatemaps;
  1869. hp:=tmodule(loaded_units.first);
  1870. while assigned(hp) do
  1871. begin
  1872. if (hp<>curr) and not assigned(hp.package) then
  1873. begin
  1874. if mf_package_deny in hp.moduleflags then
  1875. message1(package_e_unit_deny_package,hp.realmodulename^);
  1876. { part of the package's used, aka contained units? }
  1877. uu:=tused_unit(curr.used_units.first);
  1878. while assigned(uu) do
  1879. begin
  1880. if uu.u=hp then
  1881. break;
  1882. uu:=tused_unit(uu.next);
  1883. end;
  1884. if not assigned(uu) then
  1885. message2(package_n_implicit_unit_import,hp.realmodulename^,curr.realmodulename^);
  1886. end;
  1887. { was this unit listed as a contained unit? If so => error }
  1888. if (hp<>curr) and assigned(hp.package) then
  1889. begin
  1890. uu:=tused_unit(curr.used_units.first);
  1891. while assigned(uu) do
  1892. begin
  1893. if uu.u=hp then
  1894. break;
  1895. uu:=tused_unit(uu.next);
  1896. end;
  1897. if assigned(uu) then
  1898. message2(package_e_unit_already_contained_in_package,hp.realmodulename^,hp.package.realpackagename^);
  1899. end;
  1900. hp:=tmodule(hp.next);
  1901. end;
  1902. {Insert the name of the main program into the symbol table.}
  1903. if curr.realmodulename^<>'' then
  1904. tabstractunitsymtable(curr.localsymtable).insertunit(cunitsym.create(curr.realmodulename^,curr));
  1905. Message1(parser_u_parsing_implementation,curr.mainsource);
  1906. symtablestack.push(curr.localsymtable);
  1907. { create whole program optimisation information }
  1908. curr.wpoinfo:=tunitwpoinfo.create;
  1909. { should we force unit initialization? }
  1910. force_init_final:=tstaticsymtable(curr.localsymtable).needs_init_final;
  1911. if force_init_final or cnodeutils.force_init then
  1912. {init_procinfo:=gen_implicit_initfinal(mf_init,curr.localsymtable)};
  1913. { Add symbol to the exports section for win32 so smartlinking a
  1914. DLL will include the edata section }
  1915. if assigned(exportlib) and
  1916. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  1917. (mf_has_exports in curr.moduleflags) then
  1918. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',curr.localsymtable,''),0));
  1919. { all labels must be defined before generating code }
  1920. if Errorcount=0 then
  1921. tstoredsymtable(curr.localsymtable).checklabels;
  1922. symtablestack.pop(curr.localsymtable);
  1923. { consume the last point }
  1924. consume(_END);
  1925. consume(_POINT);
  1926. if (Errorcount=0) then
  1927. begin
  1928. { test static symtable }
  1929. tstoredsymtable(curr.localsymtable).allsymbolsused;
  1930. tstoredsymtable(curr.localsymtable).allprivatesused;
  1931. tstoredsymtable(curr.localsymtable).check_forwards;
  1932. { Note: all contained units are considered as used }
  1933. end;
  1934. if target_info.system in systems_all_windows+systems_nativent then
  1935. begin
  1936. main_procinfo:=create_main_proc('_PkgEntryPoint',potype_pkgstub,curr.localsymtable);
  1937. main_procinfo.procdef.aliasnames.concat('_DLLMainCRTStartup');
  1938. main_procinfo.code:=generate_pkg_stub(main_procinfo.procdef);
  1939. main_procinfo.generate_code;
  1940. end;
  1941. {$ifdef DEBUG_NODE_XML}
  1942. XMLFinalizeNodeFile('package');
  1943. {$endif DEBUG_NODE_XML}
  1944. { leave when we got an error }
  1945. if (Errorcount>0) and not status.skip_error then
  1946. begin
  1947. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  1948. status.skip_error:=true;
  1949. pkg.free;
  1950. pkg := nil;
  1951. exit;
  1952. end;
  1953. { remove all unused units, this happens when units are removed
  1954. from the uses clause in the source and the ppu was already being loaded }
  1955. hp:=tmodule(loaded_units.first);
  1956. while assigned(hp) do
  1957. begin
  1958. hp2:=hp;
  1959. hp:=tmodule(hp.next);
  1960. if assigned(hp2.package) then
  1961. add_package_unit_ref(hp2.package);
  1962. if hp2.is_unit and
  1963. not assigned(hp2.globalsymtable) then
  1964. loaded_units.remove(hp2);
  1965. end;
  1966. exportlib.ignoreduplicates:=true;
  1967. { force exports }
  1968. uu:=tused_unit(usedunits.first);
  1969. while assigned(uu) do
  1970. begin
  1971. if not assigned(systemunit) and (uu.u.modulename^='SYSTEM') then
  1972. begin
  1973. systemunit:=tglobalsymtable(uu.u.globalsymtable);
  1974. load_intern_types;
  1975. end;
  1976. if not assigned(uu.u.package) then
  1977. export_unit(uu.u);
  1978. uu:=tused_unit(uu.next);
  1979. end;
  1980. {$ifdef arm}
  1981. { Insert .pdata section for arm-wince.
  1982. It is needed for exception handling. }
  1983. if target_info.system in [system_arm_wince] then
  1984. InsertPData;
  1985. {$endif arm}
  1986. { generate debuginfo }
  1987. if (cs_debuginfo in current_settings.moduleswitches) then
  1988. current_debuginfo.inserttypeinfo;
  1989. exportlib.generatelib;
  1990. exportlib.ignoreduplicates:=false;
  1991. { create import libraries for all packages }
  1992. if packagelist.count>0 then
  1993. createimportlibfromexternals;
  1994. { generate imports }
  1995. if curr.ImportLibraryList.Count>0 then
  1996. importlib.generatelib;
  1997. { Reference all DEBUGINFO sections from the main .fpc section }
  1998. if (cs_debuginfo in current_settings.moduleswitches) then
  1999. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  2000. { insert own objectfile }
  2001. insertobjectfile(curr);
  2002. { assemble and link }
  2003. create_objectfile(curr);
  2004. { We might need the symbols info if not using
  2005. the default do_extractsymbolinfo
  2006. which is a dummy function PM }
  2007. needsymbolinfo:=do_extractsymbolinfo<>@def_extractsymbolinfo;
  2008. { release all local symtables that are not needed anymore }
  2009. if (not needsymbolinfo) then
  2010. free_localsymtables(curr.localsymtable);
  2011. { leave when we got an error }
  2012. if (Errorcount>0) and not status.skip_error then
  2013. begin
  2014. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2015. status.skip_error:=true;
  2016. pkg.free;
  2017. pkg := nil;
  2018. exit;
  2019. end;
  2020. if (not curr.is_unit) then
  2021. begin
  2022. { we add all loaded units that are not part of a package to the
  2023. package; this includes units in the "contains" section as well
  2024. as implicitly imported ones }
  2025. hp:=tmodule(loaded_units.first);
  2026. while assigned(hp) do
  2027. begin
  2028. if (hp<>curr) then
  2029. begin
  2030. if not assigned(hp.package) then
  2031. begin
  2032. pkg.addunit(hp);
  2033. check_for_indirect_package_usages(hp.used_units);
  2034. end
  2035. else
  2036. begin
  2037. pentry:=ppackageentry(packagelist.find(hp.package.packagename^));
  2038. if not assigned(pentry) then
  2039. internalerror(2015112301);
  2040. pkg.add_required_package(hp.package);
  2041. end;
  2042. end;
  2043. hp:=tmodule(hp.next);
  2044. end;
  2045. pkg.initmoduleinfo(curr);
  2046. { create the executable when we are at level 1 }
  2047. if (curr.is_initial) then
  2048. begin
  2049. { create global resource file by collecting all resource files }
  2050. CollectResourceFiles;
  2051. { write .def file }
  2052. if (cs_link_deffile in current_settings.globalswitches) then
  2053. deffile.writefile;
  2054. { generate the pcp file }
  2055. pkg.savepcp;
  2056. { insert all .o files from all loaded units and
  2057. unload the units, we don't need them anymore.
  2058. Keep the curr because that is still needed }
  2059. hp:=tmodule(loaded_units.first);
  2060. while assigned(hp) do
  2061. begin
  2062. { only link in those units which should become part of this
  2063. package }
  2064. if not assigned(hp.package) then
  2065. linker.AddModuleFiles(hp);
  2066. hp2:=tmodule(hp.next);
  2067. if (hp<>curr) and
  2068. (not needsymbolinfo) then
  2069. begin
  2070. loaded_units.remove(hp);
  2071. hp.free;
  2072. hp := nil;
  2073. end;
  2074. hp:=hp2;
  2075. end;
  2076. { add the library of directly used packages }
  2077. add_package_libs(linker);
  2078. { and now link the package library }
  2079. linker.MakeSharedLibrary
  2080. end;
  2081. { Give Fatal with error count for linker errors }
  2082. if (Errorcount>0) and not status.skip_error then
  2083. begin
  2084. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2085. status.skip_error:=true;
  2086. end;
  2087. pkg.free;
  2088. pkg := nil;
  2089. end;
  2090. end;
  2091. procedure proc_create_executable(curr, sysinitmod: tmodule; islibrary : boolean);
  2092. var
  2093. program_uses_checkpointer : boolean;
  2094. hp,hp2 : tmodule;
  2095. begin
  2096. { create global resource file by collecting all resource files }
  2097. CollectResourceFiles;
  2098. { write .def file }
  2099. if (cs_link_deffile in current_settings.globalswitches) then
  2100. deffile.writefile;
  2101. { link SysInit (if any) first, to have behavior consistent with
  2102. assembler startup files }
  2103. if assigned(sysinitmod) then
  2104. linker.AddModuleFiles(sysinitmod);
  2105. { Does any unit use checkpointer function }
  2106. program_uses_checkpointer:=false;
  2107. { insert all .o files from all loaded units and
  2108. unload the units, we don't need them anymore.
  2109. Keep the curr because that is still needed }
  2110. hp:=tmodule(loaded_units.first);
  2111. while assigned(hp) do
  2112. begin
  2113. if (hp<>sysinitmod) and not assigned(hp.package) then
  2114. begin
  2115. linker.AddModuleFiles(hp);
  2116. if mf_checkpointer_called in hp.moduleflags then
  2117. program_uses_checkpointer:=true;
  2118. end;
  2119. hp2:=tmodule(hp.next);
  2120. if assigned(hp.package) then
  2121. add_package_unit_ref(hp.package);
  2122. if (hp<>curr) and
  2123. (not needsymbolinfo) then
  2124. begin
  2125. loaded_units.remove(hp);
  2126. hp.free;
  2127. hp := nil;
  2128. end;
  2129. hp:=hp2;
  2130. end;
  2131. { free also unneeded units we didn't free before }
  2132. if not needsymbolinfo then
  2133. unloaded_units.Clear;
  2134. { Does any unit use checkpointer function }
  2135. if program_uses_checkpointer then
  2136. Message1(link_w_program_uses_checkpointer,curr.modulename^);
  2137. { add all directly used packages as libraries }
  2138. add_package_libs(linker);
  2139. { finally we can create an executable }
  2140. if curr.islibrary then
  2141. linker.MakeSharedLibrary
  2142. else
  2143. linker.MakeExecutable;
  2144. { collect all necessary information for whole-program optimization }
  2145. wpoinfomanager.extractwpoinfofromprogram;
  2146. end;
  2147. procedure proc_program_after_parsing(curr : tmodule; islibrary : boolean);
  2148. var
  2149. sysinitmod, hp,hp2 : tmodule;
  2150. resources_used : boolean;
  2151. begin
  2152. sysinitmod:=nil;
  2153. hp:=nil;
  2154. hp2:=nil;
  2155. resources_used:=false;
  2156. {$ifdef DEBUG_NODE_XML}
  2157. if IsLibrary then
  2158. XMLFinalizeNodeFile('library')
  2159. else
  2160. XMLFinalizeNodeFile('program');
  2161. {$endif DEBUG_NODE_XML}
  2162. { reset wpo flags for all defs }
  2163. reset_all_defs(curr);
  2164. if (Errorcount=0) then
  2165. begin
  2166. { test static symtable }
  2167. tstoredsymtable(curr.localsymtable).allsymbolsused;
  2168. tstoredsymtable(curr.localsymtable).allprivatesused;
  2169. tstoredsymtable(curr.localsymtable).check_forwards;
  2170. curr.allunitsused;
  2171. end;
  2172. { leave when we got an error }
  2173. if (Errorcount>0) and not status.skip_error then
  2174. begin
  2175. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2176. status.skip_error:=true;
  2177. exit;
  2178. end;
  2179. { remove all unused units, this happens when units are removed
  2180. from the uses clause in the source and the ppu was already being loaded }
  2181. hp:=tmodule(loaded_units.first);
  2182. while assigned(hp) do
  2183. begin
  2184. hp2:=hp;
  2185. hp:=tmodule(hp.next);
  2186. if hp2.is_unit and
  2187. not assigned(hp2.globalsymtable) then
  2188. begin
  2189. loaded_units.remove(hp2);
  2190. unloaded_units.concat(hp2);
  2191. end;
  2192. end;
  2193. { do we need to add the variants unit? }
  2194. maybeloadvariantsunit(curr);
  2195. { Now that everything has been compiled we know if we need resource
  2196. support. If not, remove the unit. }
  2197. resources_used:=MaybeRemoveResUnit(curr);
  2198. linker.initsysinitunitname;
  2199. if target_info.system in systems_internal_sysinit then
  2200. begin
  2201. { add start/halt unit }
  2202. sysinitmod:=AddUnit(curr,linker.sysinitunit);
  2203. end
  2204. else
  2205. sysinitmod:=nil;
  2206. {$ifdef arm}
  2207. { Insert .pdata section for arm-wince.
  2208. It is needed for exception handling. }
  2209. if target_info.system in [system_arm_wince] then
  2210. InsertPData;
  2211. {$endif arm}
  2212. cnodeutils.InsertThreadvars;
  2213. { generate rtti/init tables }
  2214. write_persistent_type_info(curr.localsymtable,false);
  2215. { if an Objective-C module, generate rtti and module info }
  2216. MaybeGenerateObjectiveCImageInfo(nil,curr.localsymtable);
  2217. { generate debuginfo }
  2218. if (cs_debuginfo in current_settings.moduleswitches) then
  2219. current_debuginfo.inserttypeinfo;
  2220. if islibrary or (target_info.system in systems_unit_program_exports) then
  2221. exportlib.generatelib;
  2222. { Reference all DEBUGINFO sections from the main .fpc section }
  2223. if (cs_debuginfo in current_settings.moduleswitches) then
  2224. current_debuginfo.referencesections(current_asmdata.asmlists[al_procedures]);
  2225. { Resource strings }
  2226. GenerateResourceStrings;
  2227. { Windows widestring needing initialization }
  2228. cnodeutils.InsertWideInits;
  2229. { Resourcestring references (const foo:string=someresourcestring) }
  2230. cnodeutils.InsertResStrInits;
  2231. { insert Tables and StackLength }
  2232. cnodeutils.InsertInitFinalTable(curr);
  2233. cnodeutils.InsertThreadvarTablesTable;
  2234. cnodeutils.InsertResourceTablesTable;
  2235. cnodeutils.InsertWideInitsTablesTable;
  2236. cnodeutils.InsertResStrTablesTable;
  2237. cnodeutils.InsertMemorySizes;
  2238. { Insert symbol to resource info }
  2239. cnodeutils.InsertResourceInfo(resources_used);
  2240. { create callframe info }
  2241. create_dwarf_frame;
  2242. { create import library for all packages }
  2243. if packagelist.count>0 then
  2244. createimportlibfromexternals;
  2245. { generate imports }
  2246. if curr.ImportLibraryList.Count>0 then
  2247. importlib.generatelib;
  2248. { insert own objectfile }
  2249. insertobjectfile(curr);
  2250. { assemble and link }
  2251. create_objectfile(curr);
  2252. { We might need the symbols info if not using
  2253. the default do_extractsymbolinfo
  2254. which is a dummy function PM }
  2255. needsymbolinfo:=
  2256. (do_extractsymbolinfo<>@def_extractsymbolinfo) or
  2257. ((current_settings.genwpoptimizerswitches*WPOptimizationsNeedingAllUnitInfo)<>[]);
  2258. { release all local symtables that are not needed anymore }
  2259. if (not needsymbolinfo) then
  2260. free_localsymtables(curr.localsymtable);
  2261. { leave when we got an error }
  2262. if (Errorcount>0) and not status.skip_error then
  2263. begin
  2264. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2265. status.skip_error:=true;
  2266. exit;
  2267. end;
  2268. { create the executable when we are at level 1 }
  2269. if (not curr.is_unit) and (curr.is_initial) then
  2270. proc_create_executable(curr,sysinitmod,islibrary);
  2271. { Give Fatal with error count for linker errors }
  2272. if (Errorcount>0) and not status.skip_error then
  2273. begin
  2274. Message1(unit_f_errors_in_unit,tostr(Errorcount));
  2275. status.skip_error:=true;
  2276. end;
  2277. curr.state:=ms_processed;
  2278. end;
  2279. function proc_program_declarations(curr : tmodule; islibrary : boolean) : boolean;
  2280. var
  2281. initpd : tprocdef;
  2282. finalize_procinfo,
  2283. init_procinfo,
  2284. main_procinfo : tcgprocinfo;
  2285. force_init_final : boolean;
  2286. begin
  2287. result:=true;
  2288. main_procinfo:=nil;
  2289. init_procinfo:=nil;
  2290. finalize_procinfo:=nil;
  2291. set_current_module(curr);
  2292. { All units are read, now give them a number }
  2293. curr.updatemaps;
  2294. connect_loaded_units(curr,nil);
  2295. { consume the semicolon after maps have been updated else conditional compiling expressions
  2296. might cause internal errors, see tw8611 }
  2297. if curr.consume_semicolon_after_uses then
  2298. begin
  2299. consume(_SEMICOLON);
  2300. curr.consume_semicolon_after_uses:=false;
  2301. end;
  2302. {Insert the name of the main program into the symbol table.}
  2303. if curr.realmodulename^<>'' then
  2304. tabstractunitsymtable(curr.localsymtable).insertunit(cunitsym.create(curr.realmodulename^,curr));
  2305. Message1(parser_u_parsing_implementation,curr.mainsource);
  2306. symtablestack.push(curr.localsymtable);
  2307. {$ifdef jvm}
  2308. { fake classdef to represent the class corresponding to the unit }
  2309. addmoduleclass(curr);
  2310. {$endif}
  2311. { Insert _GLOBAL_OFFSET_TABLE_ symbol if system uses it }
  2312. maybe_load_got(curr);
  2313. { create whole program optimisation information }
  2314. curr.wpoinfo:=tunitwpoinfo.create;
  2315. { The program initialization needs an alias, so it can be called
  2316. from the bootstrap code.}
  2317. if islibrary then
  2318. begin
  2319. initpd:=nil;
  2320. { ToDo: other systems that use indirect entry info, but check back with Windows! }
  2321. { we need to call FPC_LIBMAIN in sysinit which in turn will call PascalMain -> create dummy stub }
  2322. if target_info.system in systems_darwin then
  2323. begin
  2324. main_procinfo:=create_main_proc(make_mangledname('sysinitcallthrough',curr.localsymtable,'stub'),potype_libmainstub,curr.localsymtable);
  2325. call_through_new_name(main_procinfo.procdef,target_info.cprefix+'FPC_LIBMAIN');
  2326. initpd:=main_procinfo.procdef;
  2327. main_procinfo.free;
  2328. main_procinfo := nil;
  2329. end;
  2330. main_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,mainaliasname),potype_proginit,curr.localsymtable);
  2331. { Win32 startup code needs a single name }
  2332. if not(target_info.system in (systems_darwin+systems_aix)) then
  2333. main_procinfo.procdef.aliasnames.concat('PASCALMAIN')
  2334. else
  2335. main_procinfo.procdef.aliasnames.concat(target_info.Cprefix+'PASCALMAIN');
  2336. if not(target_info.system in systems_darwin) then
  2337. initpd:=main_procinfo.procdef;
  2338. cnodeutils.RegisterModuleInitFunction(initpd);
  2339. end
  2340. else if (target_info.system in ([system_i386_netware,system_i386_netwlibc,system_powerpc_macosclassic]+systems_darwin+systems_aix)) then
  2341. begin
  2342. { create a stub with the name of the desired main routine, with
  2343. the same signature as the C "main" function, and call through to
  2344. FPC_SYSTEMMAIN, which will initialise everything based on its
  2345. parameters. This function cannot be in the system unit, because
  2346. its name can be configured on the command line (for use with e.g.
  2347. SDL, where the main function should be called SDL_main) }
  2348. main_procinfo:=create_main_proc(mainaliasname,potype_mainstub,curr.localsymtable);
  2349. call_through_new_name(main_procinfo.procdef,target_info.cprefix+'FPC_SYSTEMMAIN');
  2350. main_procinfo.free;
  2351. { now create the PASCALMAIN routine (which will be called from
  2352. FPC_SYSTEMMAIN) }
  2353. main_procinfo:=create_main_proc('PASCALMAIN',potype_proginit,curr.localsymtable);
  2354. end
  2355. else
  2356. begin
  2357. main_procinfo:=create_main_proc(mainaliasname,potype_proginit,curr.localsymtable);
  2358. main_procinfo.procdef.aliasnames.concat('PASCALMAIN');
  2359. end;
  2360. main_procinfo.parse_body;
  2361. { save file pos for debuginfo }
  2362. curr.mainfilepos:=main_procinfo.entrypos;
  2363. { finalize? }
  2364. if token=_FINALIZATION then
  2365. begin
  2366. { Parse the finalize }
  2367. finalize_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'finalize$'),potype_unitfinalize,curr.localsymtable);
  2368. finalize_procinfo.procdef.aliasnames.insert(make_mangledname('FINALIZE$',curr.localsymtable,''));
  2369. finalize_procinfo.procdef.aliasnames.concat('PASCALFINALIZE');
  2370. finalize_procinfo.parse_body;
  2371. end;
  2372. { Generate specializations of objectdefs methods }
  2373. if Errorcount=0 then
  2374. generate_specialization_procs;
  2375. { This needs to be done before we generate the VMTs }
  2376. if (target_cpu=tsystemcpu.cpu_wasm32) then
  2377. add_synthetic_interface_classes_for_st(curr.localsymtable,true,true);
  2378. { generate construction functions for all attributes in the program }
  2379. { before write_vmts that assume attributes for methods is ready }
  2380. generate_attr_constrs(curr.used_rtti_attrs);
  2381. { Generate VMTs }
  2382. if Errorcount=0 then
  2383. write_vmts(curr.localsymtable,false);
  2384. { add implementations for synthetic method declarations added by
  2385. the compiler }
  2386. add_synthetic_method_implementations(curr.localsymtable);
  2387. { should we force unit initialization? }
  2388. force_init_final:=tstaticsymtable(curr.localsymtable).needs_init_final;
  2389. if force_init_final or cnodeutils.force_init then
  2390. init_procinfo:=gen_implicit_initfinal(curr,mf_init,curr.localsymtable);
  2391. { Add symbol to the exports section for win32 so smartlinking a
  2392. DLL will include the edata section }
  2393. if assigned(exportlib) and
  2394. (target_info.system in [system_i386_win32,system_i386_wdosx]) and
  2395. (mf_has_exports in curr.moduleflags) then
  2396. current_asmdata.asmlists[al_procedures].concat(tai_const.createname(make_mangledname('EDATA',curr.localsymtable,''),0));
  2397. if (force_init_final or cnodeutils.force_final) and
  2398. (
  2399. not assigned(finalize_procinfo)
  2400. or has_no_code(finalize_procinfo.code)
  2401. ) then
  2402. begin
  2403. { first release the not used finalize procinfo }
  2404. if assigned(finalize_procinfo) then
  2405. begin
  2406. release_proc_symbol(finalize_procinfo.procdef);
  2407. release_main_proc(curr,finalize_procinfo);
  2408. end;
  2409. finalize_procinfo:=gen_implicit_initfinal(curr,mf_finalize,curr.localsymtable);
  2410. end;
  2411. { the finalization routine of libraries is generic (and all libraries need to }
  2412. { be finalized, so they can finalize any units they use }
  2413. { Place in "pure assembler" list so that the llvm assembler writer
  2414. directly emits the generated directives }
  2415. if (islibrary) then
  2416. cnodeutils.RegisterModuleFiniFunction(search_system_proc('fpc_lib_exit'));
  2417. { all labels must be defined before generating code }
  2418. if Errorcount=0 then
  2419. tstoredsymtable(curr.localsymtable).checklabels;
  2420. { See remark in unit init/final }
  2421. main_procinfo.generate_code_tree;
  2422. main_procinfo.resetprocdef;
  2423. release_main_proc(curr,main_procinfo);
  2424. if assigned(init_procinfo) then
  2425. begin
  2426. { initialization can be implicit only }
  2427. include(curr.moduleflags,mf_init);
  2428. init_procinfo.code:=cnodeutils.wrap_proc_body(init_procinfo.procdef,init_procinfo.code);
  2429. init_procinfo.generate_code;
  2430. init_procinfo.resetprocdef;
  2431. release_main_proc(curr,init_procinfo);
  2432. end;
  2433. if assigned(finalize_procinfo) then
  2434. begin
  2435. if force_init_final or
  2436. cnodeutils.force_init or
  2437. not(has_no_code(finalize_procinfo.code)) then
  2438. begin
  2439. finalize_procinfo.code:=cnodeutils.wrap_proc_body(finalize_procinfo.procdef,finalize_procinfo.code);
  2440. finalize_procinfo.generate_code_tree;
  2441. include(curr.moduleflags,mf_finalize);
  2442. end;
  2443. finalize_procinfo.resetprocdef;
  2444. release_main_proc(curr,finalize_procinfo);
  2445. end;
  2446. symtablestack.pop(curr.localsymtable);
  2447. { consume the last point }
  2448. consume(_POINT);
  2449. proc_program_after_parsing(curr,islibrary);
  2450. end;
  2451. procedure proc_library_header(curr: tmodule);
  2452. var
  2453. program_name : ansistring;
  2454. begin
  2455. consume(_LIBRARY);
  2456. program_name:=current_scanner.orgpattern;
  2457. consume(_ID);
  2458. while token=_POINT do
  2459. begin
  2460. consume(_POINT);
  2461. program_name:=program_name+'.'+current_scanner.orgpattern;
  2462. consume(_ID);
  2463. end;
  2464. curr.setmodulename(program_name);
  2465. curr.islibrary:=true;
  2466. exportlib.preparelib(program_name);
  2467. if tf_library_needs_pic in target_info.flags then
  2468. begin
  2469. include(current_settings.moduleswitches,cs_create_pic);
  2470. { also set create_pic for all unit compilation }
  2471. include(init_settings.moduleswitches,cs_create_pic);
  2472. end;
  2473. { setup things using the switches, do this before the semicolon, because after the semicolon has been
  2474. read, all following directives are parsed as well }
  2475. setupglobalswitches;
  2476. {$ifdef DEBUG_NODE_XML}
  2477. XMLInitializeNodeFile('library', program_name);
  2478. {$endif DEBUG_NODE_XML}
  2479. end;
  2480. type
  2481. TProgramParam = record
  2482. name : ansistring;
  2483. nr : dword;
  2484. end;
  2485. TProgramParamArray = array of TProgramParam;
  2486. procedure proc_program_header(curr: tmodule; out sc : TProgramParamArray);
  2487. var
  2488. program_name : ansistring;
  2489. paramnum : integer;
  2490. begin
  2491. sc:=nil;
  2492. consume(_PROGRAM);
  2493. program_name:=current_scanner.orgpattern;
  2494. consume(_ID);
  2495. while token=_POINT do
  2496. begin
  2497. consume(_POINT);
  2498. program_name:=program_name+'.'+current_scanner.orgpattern;
  2499. consume(_ID);
  2500. end;
  2501. curr.setmodulename(program_name);
  2502. if (target_info.system in systems_unit_program_exports) then
  2503. exportlib.preparelib(program_name);
  2504. if token=_LKLAMMER then
  2505. begin
  2506. consume(_LKLAMMER);
  2507. paramnum:=1;
  2508. repeat
  2509. if m_isolike_program_para in current_settings.modeswitches then
  2510. begin
  2511. if (current_scanner.pattern<>'INPUT') and (current_scanner.pattern<>'OUTPUT') then
  2512. begin
  2513. { the symtablestack is not setup here, so text must be created later on }
  2514. Setlength(sc,length(sc)+1);
  2515. with sc[high(sc)] do
  2516. begin
  2517. name:=current_scanner.pattern;
  2518. nr:=paramnum;
  2519. end;
  2520. inc(paramnum);
  2521. end;
  2522. end;
  2523. consume(_ID);
  2524. until not try_to_consume(_COMMA);
  2525. consume(_RKLAMMER);
  2526. end;
  2527. { setup things using the switches, do this before the semicolon, because after the semicolon has been
  2528. read, all following directives are parsed as well }
  2529. setupglobalswitches;
  2530. {$ifdef DEBUG_NODE_XML}
  2531. XMLInitializeNodeFile('program', program_name);
  2532. {$endif DEBUG_NODE_XML}
  2533. end;
  2534. function proc_program(curr: tmodule; islibrary : boolean) : boolean;
  2535. var
  2536. main_file : tinputfile;
  2537. consume_semicolon_after_loaded : boolean;
  2538. ps : tprogramparasym;
  2539. textsym : ttypesym;
  2540. sc : TProgramParamArray;
  2541. i : Longint;
  2542. feature : tfeature;
  2543. load_ok : boolean;
  2544. begin
  2545. result:=true;
  2546. Status.IsLibrary:=IsLibrary;
  2547. Status.IsPackage:=false;
  2548. Status.IsExe:=true;
  2549. parse_only:=false;
  2550. consume_semicolon_after_loaded:=false;
  2551. { make the compiler happy and avoid an uninitialized variable warning on Setlength(sc,length(sc)+1); }
  2552. sc:=nil;
  2553. { DLL defaults to create reloc info }
  2554. if islibrary or (target_info.system in [system_aarch64_win64]) then
  2555. begin
  2556. if not RelocSectionSetExplicitly then
  2557. RelocSection:=true;
  2558. end;
  2559. { Relocation works only without stabs under Windows when }
  2560. { external linker (LD) is used. LD generates relocs for }
  2561. { stab sections which is not loaded in memory. It causes }
  2562. { AV error when DLL is loaded and relocation is needed. }
  2563. { Internal linker does not have this problem. }
  2564. if RelocSection and
  2565. (target_info.system in systems_all_windows+[system_i386_wdosx]) and
  2566. (cs_link_extern in current_settings.globalswitches) then
  2567. begin
  2568. include(current_settings.globalswitches,cs_link_strip);
  2569. { Warning stabs info does not work with reloc section !! }
  2570. if (cs_debuginfo in current_settings.moduleswitches) and
  2571. (target_dbg.id=dbg_stabs) then
  2572. begin
  2573. Message1(parser_w_parser_reloc_no_debug,curr.mainsource);
  2574. Message(parser_w_parser_win32_debug_needs_WN);
  2575. exclude(current_settings.moduleswitches,cs_debuginfo);
  2576. end;
  2577. end;
  2578. { get correct output names }
  2579. main_file := current_scanner.inputfile;
  2580. while assigned(main_file.next) do
  2581. main_file := main_file.next;
  2582. curr.SetFileName(main_file.path+main_file.name,true);
  2583. if islibrary then
  2584. begin
  2585. proc_library_header(curr);
  2586. consume_semicolon_after_loaded:=true;
  2587. end
  2588. else if token=_PROGRAM then
  2589. { is there an program head ? }
  2590. begin
  2591. proc_program_header(curr,sc);
  2592. consume_semicolon_after_loaded:=true;
  2593. end
  2594. else
  2595. begin
  2596. if (target_info.system in systems_unit_program_exports) then
  2597. exportlib.preparelib(curr.realmodulename^);
  2598. { setup things using the switches }
  2599. setupglobalswitches;
  2600. {$ifdef DEBUG_NODE_XML}
  2601. XMLInitializeNodeFile('program', curr.realmodulename^);
  2602. {$endif DEBUG_NODE_XML}
  2603. end;
  2604. { load all packages, so we know whether a unit is contained inside a
  2605. package or not }
  2606. load_packages;
  2607. { set implementation flag }
  2608. curr.in_interface:=false;
  2609. curr.interface_compiled:=true;
  2610. { insert after the unit symbol tables the static symbol table
  2611. of the program }
  2612. curr.localsymtable:=tstaticsymtable.create(curr.realmodulename^,curr.moduleid);
  2613. { load system unit }
  2614. load_ok:=loadsystemunit(curr);
  2615. { consume the semicolon now that the system unit is loaded }
  2616. if consume_semicolon_after_loaded then
  2617. consume(_SEMICOLON);
  2618. { global switches are read, so further changes aren't allowed }
  2619. curr.in_global:=false;
  2620. { system unit is loaded, now insert feature defines }
  2621. for feature:=low(tfeature) to high(tfeature) do
  2622. if feature in features then
  2623. def_system_macro('FPC_HAS_FEATURE_'+featurestr[feature]);
  2624. { load standard units, e.g objpas,profile unit }
  2625. load_ok:=loaddefaultunits(curr) and load_ok;
  2626. { Load units provided on the command line }
  2627. load_ok:=loadautounits(curr) and load_ok;
  2628. { insert iso program parameters }
  2629. if length(sc)>0 then
  2630. begin
  2631. textsym:=search_system_type('TEXT');
  2632. if not(assigned(textsym)) then
  2633. internalerror(2013011201);
  2634. for i:=0 to high(sc) do
  2635. begin
  2636. ps:=cprogramparasym.create(sc[i].name,sc[i].nr);
  2637. curr.localsymtable.insertsym(ps,true);
  2638. end;
  2639. end;
  2640. { Load the units used by the program we compile. }
  2641. if token=_USES then
  2642. begin
  2643. // We can do this here: if there is no uses then the namespace directive makes no sense.
  2644. if Assigned(curr) then
  2645. curr.Loadlocalnamespacelist
  2646. else
  2647. current_namespacelist:=Nil;
  2648. parseusesclause(curr);
  2649. load_ok:=loadunits(curr,false) and load_ok;
  2650. curr.consume_semicolon_after_uses:=true;
  2651. end
  2652. else
  2653. curr.consume_semicolon_after_uses:=false;
  2654. {$IFDEF EnableCTaskPPU}
  2655. if curr.is_initial then
  2656. load_ok:=false; // delay program, so ctask can finish all units
  2657. if not load_ok then
  2658. curr.state:=ms_compiling_wait;
  2659. {$ELSE}
  2660. if not load_ok then
  2661. curr.state:=ms_compiling_wait;
  2662. {$ENDIF}
  2663. { Can we continue compiling ? }
  2664. result:=curr.state<>ms_compiling_wait;
  2665. if result then
  2666. result:=proc_program_declarations(curr,islibrary)
  2667. end;
  2668. end.