compiler.pas 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This unit is the interface of the compiler which can be used by
  5. external programs to link in the compiler
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. unit compiler;
  19. {$i fpcdefs.inc}
  20. {$ifdef FPC}
  21. { One of Alpha, I386 or M68K must be defined }
  22. {$UNDEF CPUOK}
  23. {$ifdef I386}
  24. {$define CPUOK}
  25. {$endif}
  26. {$ifdef M68K}
  27. {$ifndef CPUOK}
  28. {$DEFINE CPUOK}
  29. {$else}
  30. {$fatal cannot define two CPU switches}
  31. {$endif}
  32. {$endif}
  33. {$ifdef alpha}
  34. {$ifndef CPUOK}
  35. {$DEFINE CPUOK}
  36. {$else}
  37. {$fatal cannot define two CPU switches}
  38. {$endif}
  39. {$endif}
  40. {$ifdef powerpc}
  41. {$ifndef CPUOK}
  42. {$DEFINE CPUOK}
  43. {$else}
  44. {$fatal cannot define two CPU switches}
  45. {$endif}
  46. {$endif}
  47. {$ifdef ia64}
  48. {$ifndef CPUOK}
  49. {$DEFINE CPUOK}
  50. {$else}
  51. {$fatal cannot define two CPU switches}
  52. {$endif}
  53. {$endif}
  54. {$ifdef SPARC}
  55. {$ifndef CPUOK}
  56. {$DEFINE CPUOK}
  57. {$else}
  58. {$fatal cannot define two CPU switches}
  59. {$endif}
  60. {$endif}
  61. {$ifdef x86_64}
  62. {$ifndef CPUOK}
  63. {$DEFINE CPUOK}
  64. {$else}
  65. {$fatal cannot define two CPU switches}
  66. {$endif}
  67. {$endif}
  68. {$ifndef CPUOK}
  69. {$fatal One of the switches I386, iA64, Alpha, PowerPC or M68K must be defined}
  70. {$endif}
  71. {$ifdef support_mmx}
  72. {$ifndef i386}
  73. {$fatal I386 switch must be on for MMX support}
  74. {$endif i386}
  75. {$endif support_mmx}
  76. {$endif}
  77. interface
  78. uses
  79. {$ifdef fpc}
  80. {$ifdef GO32V2}
  81. emu387,
  82. {$endif GO32V2}
  83. {$endif}
  84. {$ifdef USEEXCEPT}
  85. tpexcept,
  86. {$endif USEEXCEPT}
  87. {$ifdef BrowserLog}
  88. browlog,
  89. {$endif BrowserLog}
  90. {$ifdef Delphi}
  91. dmisc,
  92. {$else Delphi}
  93. dos,
  94. {$endif Delphi}
  95. verbose,comphook,systems,
  96. cutils,cclasses,globals,options,fmodule,parser,symtable,
  97. assemble,link,import,export,tokens,pass_1
  98. { cpu overrides }
  99. ,cpuswtch
  100. { cpu codegenerator }
  101. {$ifndef NOPASS2}
  102. ,cpunode
  103. {$endif}
  104. { cpu targets }
  105. ,cputarg
  106. { cpu parameter handling }
  107. ,cpupara
  108. ;
  109. function Compile(const cmd:string):longint;
  110. implementation
  111. uses
  112. aasmcpu;
  113. var
  114. CompilerInitedAfterArgs,
  115. CompilerInited : boolean;
  116. olddo_stop : tstopprocedure;
  117. {$ifdef USEEXCEPT}
  118. procedure RecoverStop;
  119. begin
  120. if recoverpospointer<>nil then
  121. LongJmp(recoverpospointer^,1)
  122. else
  123. Do_Halt(1);
  124. end;
  125. {$endif USEEXCEPT}
  126. {$ifdef EXTDEBUG}
  127. {$ifdef FPC}
  128. Var
  129. LostMemory : longint;
  130. Procedure CheckMemory(LostMemory : longint);
  131. begin
  132. if LostMemory<>0 then
  133. begin
  134. Writeln('Memory Lost = '+tostr(LostMemory));
  135. {$ifdef DEBUG}
  136. def_gdb_stop(V_Warning);
  137. {$endif DEBUG}
  138. end;
  139. end;
  140. {$endif FPC}
  141. {$endif EXTDEBUG}
  142. {****************************************************************************
  143. Compiler
  144. ****************************************************************************}
  145. procedure DoneCompiler;
  146. begin
  147. if not CompilerInited then
  148. exit;
  149. { Free compiler if args are read }
  150. {$ifdef BrowserLog}
  151. DoneBrowserLog;
  152. {$endif BrowserLog}
  153. {$ifdef BrowserCol}
  154. do_doneSymbolInfo;
  155. {$endif BrowserCol}
  156. if CompilerInitedAfterArgs then
  157. begin
  158. CompilerInitedAfterArgs:=false;
  159. DoneParser;
  160. DoneImport;
  161. DoneExport;
  162. DoneLinker;
  163. DoneAssembler;
  164. DoneAsm;
  165. end;
  166. { Free memory for the others }
  167. CompilerInited:=false;
  168. DoneSymtable;
  169. DoneGlobals;
  170. donetokens;
  171. {$ifdef USEEXCEPT}
  172. recoverpospointer:=nil;
  173. longjump_used:=false;
  174. {$endif USEEXCEPT}
  175. end;
  176. procedure InitCompiler(const cmd:string);
  177. begin
  178. if CompilerInited then
  179. DoneCompiler;
  180. { inits which need to be done before the arguments are parsed }
  181. InitSystems;
  182. { globals depends on source_info so it must be after systems }
  183. InitGlobals;
  184. { verbose depends on exe_path and must be after globals }
  185. InitVerbose;
  186. {$ifdef BrowserLog}
  187. InitBrowserLog;
  188. {$endif BrowserLog}
  189. {$ifdef BrowserCol}
  190. do_initSymbolInfo;
  191. {$endif BrowserCol}
  192. inittokens;
  193. InitSymtable;
  194. CompilerInited:=true;
  195. { this is needed here for the IDE
  196. in case of compilation failure
  197. at the previous compile }
  198. current_module:=nil;
  199. { read the arguments }
  200. read_arguments(cmd);
  201. { inits which depend on arguments }
  202. InitParser;
  203. InitImport;
  204. InitExport;
  205. InitLinker;
  206. InitAssembler;
  207. InitAsm;
  208. CompilerInitedAfterArgs:=true;
  209. end;
  210. procedure minimal_stop;
  211. begin
  212. DoneCompiler;
  213. olddo_stop{$ifdef FPCPROCVAR}(){$endif};
  214. end;
  215. function Compile(const cmd:string):longint;
  216. {$ifdef fpc}
  217. {$maxfpuregisters 0}
  218. {$endif fpc}
  219. procedure writepathlist(w:longint;l:TSearchPathList);
  220. var
  221. hp : tstringlistitem;
  222. begin
  223. hp:=tstringlistitem(l.first);
  224. while assigned(hp) do
  225. begin
  226. Message1(w,hp.str);
  227. hp:=tstringlistitem(hp.next);
  228. end;
  229. end;
  230. function getrealtime : real;
  231. var
  232. h,m,s,s100 : word;
  233. begin
  234. gettime(h,m,s,s100);
  235. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  236. end;
  237. var
  238. starttime : real;
  239. {$ifdef USEEXCEPT}
  240. recoverpos : jmp_buf;
  241. {$endif}
  242. begin
  243. olddo_stop:=do_stop;
  244. do_stop:={$ifdef FPCPROCVAR}@{$endif}minimal_stop;
  245. { Initialize the compiler }
  246. InitCompiler(cmd);
  247. { show some info }
  248. Message1(general_t_compilername,FixFileName(system.paramstr(0)));
  249. Message1(general_d_sourceos,source_info.name);
  250. Message1(general_i_targetos,target_info.name);
  251. Message1(general_t_exepath,exepath);
  252. WritePathList(general_t_unitpath,unitsearchpath);
  253. WritePathList(general_t_includepath,includesearchpath);
  254. WritePathList(general_t_librarypath,librarysearchpath);
  255. WritePathList(general_t_objectpath,objectsearchpath);
  256. {$ifdef USEEXCEPT}
  257. if setjmp(recoverpos)=0 then
  258. begin
  259. recoverpospointer:=@recoverpos;
  260. do_stop:={$ifdef FPCPROCVAR}@{$endif}recoverstop;
  261. {$endif USEEXCEPT}
  262. starttime:=getrealtime;
  263. {$ifdef PREPROCWRITE}
  264. if parapreprocess then
  265. parser.preprocess(inputdir+inputfile+inputextension)
  266. else
  267. {$endif PREPROCWRITE}
  268. parser.compile(inputdir+inputfile+inputextension);
  269. if status.errorcount=0 then
  270. begin
  271. starttime:=getrealtime-starttime;
  272. if starttime<0 then
  273. starttime:=starttime+3600.0*24.0;
  274. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  275. '.'+tostr(trunc(frac(starttime)*10)));
  276. end;
  277. {$ifdef USEEXCEPT}
  278. end;
  279. {$endif USEEXCEPT}
  280. { Stop is always called, so we come here when a program is compiled or not }
  281. do_stop:=olddo_stop;
  282. { Stop the compiler, frees also memory }
  283. { no message possible after this !! }
  284. DoneCompiler;
  285. { Set the return value if an error has occurred }
  286. if status.errorcount=0 then
  287. Compile:=0
  288. else
  289. Compile:=1;
  290. DoneVerbose;
  291. {$ifdef EXTDEBUG}
  292. {$ifdef FPC}
  293. LostMemory:=system.HeapSize-MemAvail-EntryMemUsed;
  294. CheckMemory(LostMemory);
  295. {$endif FPC}
  296. Writeln('Repetitive firstpass = '+tostr(firstpass_several)+'/'+tostr(total_of_firstpass));
  297. Writeln('Repetitive resulttypepass = ',multiresulttypepasscnt,'/',resulttypepasscnt);
  298. {$endif EXTDEBUG}
  299. {$ifdef MEMDEBUG}
  300. Writeln('Memory used: ',system.Heapsize);
  301. {$endif}
  302. {$ifdef fixLeaksOnError}
  303. do_stop{$ifdef FPCPROCVAR}(){$endif};
  304. {$endif fixLeaksOnError}
  305. end;
  306. end.
  307. {
  308. $Log$
  309. Revision 1.32 2002-07-11 14:41:27 florian
  310. * start of the new generic parameter handling
  311. Revision 1.31 2002/07/04 19:00:23 florian
  312. + x86_64 define added
  313. Revision 1.30 2002/07/01 18:46:22 peter
  314. * internal linker
  315. * reorganized aasm layer
  316. Revision 1.29 2002/05/18 13:34:06 peter
  317. * readded missing revisions
  318. Revision 1.28 2002/05/16 19:46:35 carl
  319. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  320. + try to fix temp allocation (still in ifdef)
  321. + generic constructor calls
  322. + start of tassembler / tmodulebase class cleanup
  323. Revision 1.26 2002/05/12 16:53:05 peter
  324. * moved entry and exitcode to ncgutil and cgobj
  325. * foreach gets extra argument for passing local data to the
  326. iterator function
  327. * -CR checks also class typecasts at runtime by changing them
  328. into as
  329. * fixed compiler to cycle with the -CR option
  330. * fixed stabs with elf writer, finally the global variables can
  331. be watched
  332. * removed a lot of routines from cga unit and replaced them by
  333. calls to cgobj
  334. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  335. u32bit then the other is typecasted also to u32bit without giving
  336. a rangecheck warning/error.
  337. * fixed pascal calling method with reversing also the high tree in
  338. the parast, detected by tcalcst3 test
  339. Revision 1.25 2002/04/15 19:53:54 peter
  340. * fixed conflicts between the last 2 commits
  341. Revision 1.24 2002/04/15 18:56:42 carl
  342. + InitAsm
  343. Revision 1.23 2002/03/24 19:05:31 carl
  344. + patch for SPARC from Mazen NEIFER
  345. }