compiler.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. {
  19. possible compiler switches:
  20. -----------------------------------------------------------------
  21. TP to compile the compiler with Turbo or Borland Pascal
  22. I386 generate a compiler for the Intel i386+
  23. M68K generate a compiler for the M68000
  24. GDB support of the GNU Debugger
  25. EXTDEBUG some extra debug code is executed
  26. SUPPORT_MMX only i386: releases the compiler switch
  27. MMX which allows the compiler to generate
  28. MMX instructions
  29. EXTERN_MSG Don't compile the msgfiles in the compiler, always
  30. use external messagefiles
  31. NOAG386INT no Intel Assembler output
  32. NOAG386NSM no NASM output
  33. -----------------------------------------------------------------
  34. }
  35. {$ifdef FPC}
  36. { One of Alpha, I386 or M68K must be defined }
  37. {$UNDEF CPUOK}
  38. {$ifdef I386}
  39. {$define CPUOK}
  40. {$endif}
  41. {$ifdef M68K}
  42. {$ifndef CPUOK}
  43. {$DEFINE CPUOK}
  44. {$else}
  45. {$fatal cannot define two CPU switches}
  46. {$endif}
  47. {$endif}
  48. {$ifdef alpha}
  49. {$ifndef CPUOK}
  50. {$DEFINE CPUOK}
  51. {$else}
  52. {$fatal cannot define two CPU switches}
  53. {$endif}
  54. {$endif}
  55. {$ifdef powerpc}
  56. {$ifndef CPUOK}
  57. {$DEFINE CPUOK}
  58. {$else}
  59. {$fatal cannot define two CPU switches}
  60. {$endif}
  61. {$endif}
  62. {$ifndef CPUOK}
  63. {$fatal One of the switches I386, Alpha, PowerPC or M68K must be defined}
  64. {$endif}
  65. {$ifdef support_mmx}
  66. {$ifndef i386}
  67. {$fatal I386 switch must be on for MMX support}
  68. {$endif i386}
  69. {$endif support_mmx}
  70. {$endif}
  71. unit compiler;
  72. interface
  73. { Use exception catching so the compiler goes futher after a Stop }
  74. {$ifndef NOUSEEXCEPT}
  75. {$ifdef i386}
  76. {$define USEEXCEPT}
  77. {$endif}
  78. {$ifdef TP}
  79. {$ifdef DPMI}
  80. {$undef USEEXCEPT}
  81. {$endif}
  82. {$endif}
  83. {$endif ndef NOUSEEXCEPT}
  84. uses
  85. {$ifdef fpc}
  86. {$ifdef GO32V2}
  87. emu387,
  88. { dpmiexcp, }
  89. {$endif GO32V2}
  90. {$ifdef LINUX}
  91. catch,
  92. {$endif LINUX}
  93. {$endif}
  94. {$ifdef USEEXCEPT}
  95. tpexcept,
  96. {$endif USEEXCEPT}
  97. {$ifdef BrowserLog}
  98. browlog,
  99. {$endif BrowserLog}
  100. {$ifdef Delphi}
  101. dmisc,
  102. {$else Delphi}
  103. dos,
  104. {$endif Delphi}
  105. verbose,comphook,systems,
  106. cobjects,globals,options,parser,symtable,link,import,export,tokens;
  107. function Compile(const cmd:string):longint;
  108. Const
  109. { do we need to link }
  110. IsExe : boolean = false;
  111. implementation
  112. uses
  113. cpubase;
  114. var
  115. CompilerInitedAfterArgs,
  116. CompilerInited : boolean;
  117. olddo_stop : tstopprocedure;
  118. {$ifdef USEEXCEPT}
  119. procedure RecoverStop;{$ifndef FPC}far;{$endif}
  120. begin
  121. if recoverpospointer<>nil then
  122. LongJmp(recoverpospointer^,1)
  123. else
  124. Do_Halt(1);
  125. end;
  126. {$endif USEEXCEPT}
  127. {$ifdef EXTDEBUG}
  128. {$ifdef FPC}
  129. Var
  130. LostMemory : longint;
  131. Procedure CheckMemory(LostMemory : longint);
  132. begin
  133. if LostMemory<>0 then
  134. begin
  135. Writeln('Memory Lost = '+tostr(LostMemory));
  136. {$ifdef DEBUG}
  137. def_gdb_stop(V_Warning);
  138. {$endif DEBUG}
  139. end;
  140. end;
  141. {$endif FPC}
  142. {$endif EXTDEBUG}
  143. {****************************************************************************
  144. Compiler
  145. ****************************************************************************}
  146. procedure DoneCompiler;
  147. begin
  148. if not CompilerInited then
  149. exit;
  150. { Free compiler if args are read }
  151. {$ifdef BrowserLog}
  152. DoneBrowserLog;
  153. {$endif BrowserLog}
  154. {$ifdef BrowserCol}
  155. do_doneSymbolInfo;
  156. {$endif BrowserCol}
  157. if CompilerInitedAfterArgs then
  158. begin
  159. CompilerInitedAfterArgs:=false;
  160. doneparser;
  161. DoneImport;
  162. DoneExport;
  163. DoneLinker;
  164. DoneCpu;
  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. InitVerbose;
  183. {$ifdef BrowserLog}
  184. InitBrowserLog;
  185. {$endif BrowserLog}
  186. {$ifdef BrowserCol}
  187. do_initSymbolInfo;
  188. {$endif BrowserCol}
  189. InitGlobals;
  190. inittokens;
  191. InitSymtable;
  192. CompilerInited:=true;
  193. { read the arguments }
  194. read_arguments(cmd);
  195. { inits which depend on arguments }
  196. initparser;
  197. InitImport;
  198. InitExport;
  199. InitLinker;
  200. InitCpu;
  201. CompilerInitedAfterArgs:=true;
  202. end;
  203. procedure minimal_stop;{$ifndef fpc}far;{$endif}
  204. begin
  205. DoneCompiler;
  206. olddo_stop;
  207. end;
  208. function Compile(const cmd:string):longint;
  209. {$ifdef fpc}
  210. {$maxfpuregisters 0}
  211. {$endif fpc}
  212. procedure writepathlist(w:longint;l:TSearchPathList);
  213. var
  214. hp : pstringqueueitem;
  215. begin
  216. hp:=l.first;
  217. while assigned(hp) do
  218. begin
  219. Message1(w,hp^.data^);
  220. hp:=hp^.next;
  221. end;
  222. end;
  223. function getrealtime : real;
  224. var
  225. h,m,s,s100 : word;
  226. begin
  227. gettime(h,m,s,s100);
  228. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  229. end;
  230. var
  231. starttime : real;
  232. {$ifdef USEEXCEPT}
  233. recoverpos : jmp_buf;
  234. {$endif}
  235. begin
  236. olddo_stop:=do_stop;
  237. {$ifdef TP}
  238. do_stop:=minimal_stop;
  239. {$else TP}
  240. do_stop:=@minimal_stop;
  241. {$endif TP}
  242. { Initialize the compiler }
  243. InitCompiler(cmd);
  244. { show some info }
  245. Message1(general_t_compilername,FixFileName(paramstr(0)));
  246. Message1(general_d_sourceos,source_os.name);
  247. Message1(general_i_targetos,target_os.name);
  248. Message1(general_t_exepath,exepath);
  249. WritePathList(general_t_unitpath,unitsearchpath);
  250. WritePathList(general_t_includepath,includesearchpath);
  251. WritePathList(general_t_librarypath,librarysearchpath);
  252. WritePathList(general_t_objectpath,objectsearchpath);
  253. {$ifdef TP}
  254. {$ifndef Delphi}
  255. Comment(V_Info,'Memory: '+tostr(MemAvail)+' Bytes Free');
  256. {$endif Delphi}
  257. {$endif}
  258. {$ifdef USEEXCEPT}
  259. if setjmp(recoverpos)=0 then
  260. begin
  261. recoverpospointer:=@recoverpos;
  262. {$ifdef TP}
  263. do_stop:=recoverstop;
  264. {$else TP}
  265. do_stop:=@recoverstop;
  266. {$endif TP}
  267. {$endif USEEXCEPT}
  268. starttime:=getrealtime;
  269. if parapreprocess then
  270. parser.preprocess(inputdir+inputfile+inputextension)
  271. else
  272. parser.compile(inputdir+inputfile+inputextension,false);
  273. if status.errorcount=0 then
  274. begin
  275. starttime:=getrealtime-starttime;
  276. if starttime<0 then
  277. starttime:=starttime+3600.0*24.0;
  278. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  279. '.'+tostr(trunc(frac(starttime)*10)));
  280. end;
  281. {$ifdef USEEXCEPT}
  282. end;
  283. {$endif USEEXCEPT}
  284. { Stop is always called, so we come here when a program is compiled or not }
  285. do_stop:=olddo_stop;
  286. { Stop the compiler, frees also memory }
  287. { no message possible after this !! }
  288. DoneCompiler;
  289. { Set the return value if an error has occurred }
  290. if status.errorcount=0 then
  291. Compile:=0
  292. else
  293. Compile:=1;
  294. DoneVerbose;
  295. {$ifdef EXTDEBUG}
  296. {$ifdef FPC}
  297. LostMemory:=system.HeapSize-MemAvail-EntryMemUsed;
  298. CheckMemory(LostMemory);
  299. {$endif FPC}
  300. {$ifndef newcg}
  301. Writeln('Repetitive firstpass = '+tostr(firstpass_several)+'/'+tostr(total_of_firstpass));
  302. {$endif newcg}
  303. {$endif EXTDEBUG}
  304. {$ifdef fixLeaksOnError}
  305. {$ifdef tp}
  306. do_stop;
  307. {$else tp}
  308. do_stop();
  309. {$endif tp}
  310. {$endif fixLeaksOnError}
  311. end;
  312. end.
  313. {
  314. $Log$
  315. Revision 1.1 2000-07-13 06:29:48 michael
  316. + Initial import
  317. Revision 1.51 2000/06/30 20:23:33 peter
  318. * new message files layout with msg numbers (but still no code to
  319. show the number on the screen)
  320. Revision 1.50 2000/05/29 10:04:40 pierre
  321. * New bunch of Gabor changes
  322. Revision 1.49 2000/05/03 16:31:22 pierre
  323. + easier debug when memory is lost
  324. Revision 1.48 2000/04/05 21:18:04 pierre
  325. * set NOUSEEXCEPT to remove use of setjump/longjump
  326. Revision 1.47 2000/03/18 15:05:33 jonas
  327. + added $maxfpuregisters 0 for compile() procedure
  328. Revision 1.46 2000/02/09 13:22:50 peter
  329. * log truncated
  330. Revision 1.45 2000/01/11 17:16:04 jonas
  331. * removed a lot of memory leaks when an error is encountered (caused by
  332. procinfo and pstringcontainers). There are still plenty left though :)
  333. Revision 1.44 2000/01/11 16:56:22 jonas
  334. - removed call to do_stop at the end of compile() since it obviously breaks the
  335. automatic compiling of units. Make cycle worked though! 8)
  336. Revision 1.43 2000/01/11 16:53:24 jonas
  337. + call do_stop at the end of compile()
  338. Revision 1.42 2000/01/07 01:14:23 peter
  339. * updated copyright to 2000
  340. Revision 1.41 1999/12/02 17:34:34 peter
  341. * preprocessor support. But it fails on the caret in type blocks
  342. Revision 1.40 1999/11/18 13:43:48 pierre
  343. + IsExe global var needed for IDE
  344. Revision 1.39 1999/11/12 11:03:50 peter
  345. * searchpaths changed to stringqueue object
  346. Revision 1.38 1999/11/09 23:47:53 pierre
  347. + minimal_stop to avoid memory loss with -iTO switch
  348. Revision 1.37 1999/11/06 14:34:20 peter
  349. * truncated log to 20 revs
  350. Revision 1.36 1999/10/12 21:20:41 florian
  351. * new codegenerator compiles again
  352. Revision 1.35 1999/09/28 19:48:45 florian
  353. * bug 617 fixed
  354. Revision 1.34 1999/09/16 23:05:52 florian
  355. * m68k compiler is again compilable (only gas writer, no assembler reader)
  356. Revision 1.33 1999/09/07 15:10:04 pierre
  357. * use do_halt instead of halt
  358. Revision 1.32 1999/09/02 18:47:44 daniel
  359. * Could not compile with TP, some arrays moved to heap
  360. * NOAG386BIN default for TP
  361. * AG386* files were not compatible with TP, fixed.
  362. Revision 1.31 1999/08/20 10:17:01 michael
  363. + Patch from pierre
  364. Revision 1.30 1999/08/11 17:26:31 peter
  365. * tlinker object is now inherited for win32 and dos
  366. * postprocessexecutable is now a method of tlinker
  367. Revision 1.29 1999/08/09 22:13:43 peter
  368. * fixed writing of lost memory which should be after donecompiler
  369. Revision 1.28 1999/08/04 13:02:40 jonas
  370. * all tokens now start with an underscore
  371. * PowerPC compiles!!
  372. Revision 1.27 1999/08/02 21:28:56 florian
  373. * the main branch psub.pas is now used for
  374. newcg compiler
  375. Revision 1.26 1999/08/02 20:46:57 michael
  376. * Alpha aware switch detection
  377. }