compiler.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  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. {$endif}
  91. {$ifdef USEEXCEPT}
  92. tpexcept,
  93. {$endif USEEXCEPT}
  94. {$ifdef BrowserLog}
  95. browlog,
  96. {$endif BrowserLog}
  97. {$ifdef Delphi}
  98. dmisc,
  99. {$else Delphi}
  100. dos,
  101. {$endif Delphi}
  102. verbose,comphook,systems,
  103. cobjects,globals,options,parser,symtable,link,import,export,tokens;
  104. function Compile(const cmd:string):longint;
  105. Const
  106. { do we need to link }
  107. IsExe : boolean = false;
  108. implementation
  109. uses
  110. cpubase;
  111. var
  112. CompilerInitedAfterArgs,
  113. CompilerInited : boolean;
  114. olddo_stop : tstopprocedure;
  115. {$ifdef USEEXCEPT}
  116. procedure RecoverStop;{$ifndef FPC}far;{$endif}
  117. begin
  118. if recoverpospointer<>nil then
  119. LongJmp(recoverpospointer^,1)
  120. else
  121. Do_Halt(1);
  122. end;
  123. {$endif USEEXCEPT}
  124. {$ifdef EXTDEBUG}
  125. {$ifdef FPC}
  126. Var
  127. LostMemory : longint;
  128. Procedure CheckMemory(LostMemory : longint);
  129. begin
  130. if LostMemory<>0 then
  131. begin
  132. Writeln('Memory Lost = '+tostr(LostMemory));
  133. {$ifdef DEBUG}
  134. def_gdb_stop(V_Warning);
  135. {$endif DEBUG}
  136. end;
  137. end;
  138. {$endif FPC}
  139. {$endif EXTDEBUG}
  140. {****************************************************************************
  141. Compiler
  142. ****************************************************************************}
  143. procedure DoneCompiler;
  144. begin
  145. if not CompilerInited then
  146. exit;
  147. { Free compiler if args are read }
  148. {$ifdef BrowserLog}
  149. DoneBrowserLog;
  150. {$endif BrowserLog}
  151. {$ifdef BrowserCol}
  152. do_doneSymbolInfo;
  153. {$endif BrowserCol}
  154. if CompilerInitedAfterArgs then
  155. begin
  156. CompilerInitedAfterArgs:=false;
  157. doneparser;
  158. DoneImport;
  159. DoneExport;
  160. DoneLinker;
  161. DoneCpu;
  162. end;
  163. { Free memory for the others }
  164. CompilerInited:=false;
  165. DoneSymtable;
  166. DoneGlobals;
  167. donetokens;
  168. {$ifdef USEEXCEPT}
  169. recoverpospointer:=nil;
  170. longjump_used:=false;
  171. {$endif USEEXCEPT}
  172. end;
  173. procedure InitCompiler(const cmd:string);
  174. begin
  175. if CompilerInited then
  176. DoneCompiler;
  177. { inits which need to be done before the arguments are parsed }
  178. InitSystems;
  179. InitVerbose;
  180. {$ifdef BrowserLog}
  181. InitBrowserLog;
  182. {$endif BrowserLog}
  183. {$ifdef BrowserCol}
  184. do_initSymbolInfo;
  185. {$endif BrowserCol}
  186. InitGlobals;
  187. inittokens;
  188. InitSymtable;
  189. CompilerInited:=true;
  190. { read the arguments }
  191. read_arguments(cmd);
  192. { inits which depend on arguments }
  193. initparser;
  194. InitImport;
  195. InitExport;
  196. InitLinker;
  197. InitCpu;
  198. CompilerInitedAfterArgs:=true;
  199. end;
  200. procedure minimal_stop;{$ifndef fpc}far;{$endif}
  201. begin
  202. DoneCompiler;
  203. olddo_stop;
  204. end;
  205. function Compile(const cmd:string):longint;
  206. {$ifdef fpc}
  207. {$maxfpuregisters 0}
  208. {$endif fpc}
  209. procedure writepathlist(w:longint;l:TSearchPathList);
  210. var
  211. hp : pstringqueueitem;
  212. begin
  213. hp:=l.first;
  214. while assigned(hp) do
  215. begin
  216. Message1(w,hp^.data^);
  217. hp:=hp^.next;
  218. end;
  219. end;
  220. function getrealtime : real;
  221. var
  222. h,m,s,s100 : word;
  223. begin
  224. gettime(h,m,s,s100);
  225. getrealtime:=h*3600.0+m*60.0+s+s100/100.0;
  226. end;
  227. var
  228. starttime : real;
  229. {$ifdef USEEXCEPT}
  230. recoverpos : jmp_buf;
  231. {$endif}
  232. begin
  233. olddo_stop:=do_stop;
  234. {$ifdef TP}
  235. do_stop:=minimal_stop;
  236. {$else TP}
  237. do_stop:=@minimal_stop;
  238. {$endif TP}
  239. { Initialize the compiler }
  240. InitCompiler(cmd);
  241. { show some info }
  242. Message1(general_t_compilername,FixFileName(paramstr(0)));
  243. Message1(general_d_sourceos,source_os.name);
  244. Message1(general_i_targetos,target_os.name);
  245. Message1(general_t_exepath,exepath);
  246. WritePathList(general_t_unitpath,unitsearchpath);
  247. WritePathList(general_t_includepath,includesearchpath);
  248. WritePathList(general_t_librarypath,librarysearchpath);
  249. WritePathList(general_t_objectpath,objectsearchpath);
  250. {$ifdef TP}
  251. {$ifndef Delphi}
  252. Comment(V_Info,'Memory: '+tostr(MemAvail)+' Bytes Free');
  253. {$endif Delphi}
  254. {$endif}
  255. {$ifdef USEEXCEPT}
  256. if setjmp(recoverpos)=0 then
  257. begin
  258. recoverpospointer:=@recoverpos;
  259. {$ifdef TP}
  260. do_stop:=recoverstop;
  261. {$else TP}
  262. do_stop:=@recoverstop;
  263. {$endif TP}
  264. {$endif USEEXCEPT}
  265. starttime:=getrealtime;
  266. if parapreprocess then
  267. parser.preprocess(inputdir+inputfile+inputextension)
  268. else
  269. parser.compile(inputdir+inputfile+inputextension,false);
  270. if status.errorcount=0 then
  271. begin
  272. starttime:=getrealtime-starttime;
  273. if starttime<0 then
  274. starttime:=starttime+3600.0*24.0;
  275. Message2(general_i_abslines_compiled,tostr(status.compiledlines),tostr(trunc(starttime))+
  276. '.'+tostr(trunc(frac(starttime)*10)));
  277. end;
  278. {$ifdef USEEXCEPT}
  279. end;
  280. {$endif USEEXCEPT}
  281. { Stop is always called, so we come here when a program is compiled or not }
  282. do_stop:=olddo_stop;
  283. { Stop the compiler, frees also memory }
  284. { no message possible after this !! }
  285. DoneCompiler;
  286. { Set the return value if an error has occurred }
  287. if status.errorcount=0 then
  288. Compile:=0
  289. else
  290. Compile:=1;
  291. DoneVerbose;
  292. {$ifdef EXTDEBUG}
  293. {$ifdef FPC}
  294. LostMemory:=system.HeapSize-MemAvail-EntryMemUsed;
  295. CheckMemory(LostMemory);
  296. {$endif FPC}
  297. {$ifndef newcg}
  298. Writeln('Repetitive firstpass = '+tostr(firstpass_several)+'/'+tostr(total_of_firstpass));
  299. {$endif newcg}
  300. {$endif EXTDEBUG}
  301. {$ifdef MEMDEBUG}
  302. Writeln('Memory used: ',system.Heapsize);
  303. {$endif}
  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.4 2000-08-21 09:14:40 jonas
  316. - removed catch unit from uses clause for Linux (clashed with fpcatch
  317. from IDE and is already in pp.pas for command line compiler) (merged
  318. from fixes branch)
  319. Revision 1.3 2000/08/04 22:00:50 peter
  320. * merges from fixes
  321. Revision 1.2 2000/07/13 11:32:38 michael
  322. + removed logs
  323. }