3 Copyright (c) 1998-2000 by Florian Klaempfl
5 Handles the parsing and loading of the modules (ppufiles)
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 ****************************************************************************
24 { close old_current_ppu on system that are
25 short on file handles like DOS system PM }
27 {$define SHORT_ON_FILE_HANDLES}
30 {$define SHORT_ON_FILE_HANDLES}
38 procedure proc_program(islibrary
: boolean);
44 globtype
,version
,systems
,tokens
,
45 cobjects
,comphook
,compiler
,
46 globals
,verbose
,files
,
47 symconst
,symtable
,aasm
,types
,
56 link
,assemble
,import
,export,gendef
,ppu
,comprsrc
,
57 cresstr
,cpubase
,cpuasm
,
61 scanner
,pbase
,psystem
,pdecl
,psub
,parser
;
63 procedure create_objectfile
;
65 { create the .s file and assemble it }
68 { Also create a smartlinked version ? }
69 if (cs_create_smart
in aktmoduleswitches
) then
71 { regenerate the importssection for win32 }
72 if assigned(importssection
) and
73 (target_info
.target
=target_i386_win32
) then
75 importssection
^.clear
;
76 importlib
^.generatesmartlib
;
80 if target_asm
.needar
then
81 Linker
^.MakeStaticLibrary
;
89 procedure insertobjectfile
;
90 { Insert the used object file for this unit in the used list for this unit }
92 current_module
^.linkunitofiles
.insert(current_module
^.objfilename
^,link_static
);
93 current_module
^.flags
:=current_module
^.flags
or uf_static_linked
;
95 if (cs_create_smart
in aktmoduleswitches
) then
97 current_module
^.linkunitstaticlibs
.insert(current_module
^.staticlibfilename
^,link_smart
);
98 current_module
^.flags
:=current_module
^.flags
or uf_smart_linked
;
103 procedure insertsegment
;
105 procedure fixseg(p
:paasmoutput
;sec
:tsection
);
107 p
^.insert(new(pai_section
,init(sec
)));
108 if (cs_create_smart
in aktmoduleswitches
) then
109 p
^.insert(new(pai_cut
,init
));
110 p
^.concat(new(pai_section
,init(sec_none
)));
114 { Insert Ident of the compiler }
115 if (not (cs_create_smart
in aktmoduleswitches
))
117 and (not current_module
^.is_unit
)
121 datasegment
^.insert(new(pai_align
,init(4)));
122 datasegment
^.insert(new(pai_string
,init('FPC '+full_version_string
+
123 ' ['+date_string
+'] for '+target_cpu_string
+' - '+target_info
.short_name
)));
125 { finish codesegment }
126 codesegment
^.concat(new(pai_align
,init(16)));
127 { Insert start and end of sections }
128 fixseg(codesegment
,sec_code
);
129 fixseg(datasegment
,sec_data
);
130 fixseg(bsssegment
,sec_bss
);
131 { we should use .rdata section for these two no ? }
132 { .rdata is a read only data section (PM) }
133 fixseg(rttilist
,sec_data
);
134 fixseg(consts
,sec_data
);
135 if assigned(resourcestringlist
) then
136 fixseg(resourcestringlist
,sec_data
);
138 if assigned(debuglist
) then
140 debuglist
^.insert(new(pai_symbol
,initname('gcc2_compiled',0)));
141 debuglist
^.insert(new(pai_symbol
,initname('fpc_compiled',0)));
142 fixseg(debuglist
,sec_code
);
148 Procedure InsertResourceTablesTable
;
151 ResourceStringTables
: taasmoutput
;
154 ResourceStringTables
.init
;
156 hp
:=pused_unit(usedunits
.first
);
157 while assigned(hp
) do
159 If (hp
^.u
^.flags
and uf_has_resources
)=uf_has_resources
then
161 ResourceStringTables
.concat(new(pai_const_symbol
,initname(hp
^.u
^.modulename
^+'_RESOURCESTRINGLIST')));
164 hp
:=Pused_unit(hp
^.next
);
166 { Add program resources, if any }
167 If ResourceStringList
<>Nil then
169 ResourceStringTables
.concat(new(pai_const_symbol
,initname(Current_Module
^.modulename
^+'_RESOURCESTRINGLIST')));
173 { doesn't work because of bug in the compiler !! (JM)
174 With ResourceStringTables do}
176 ResourceStringTables
.insert(new(pai_const
,init_32bit(count
)));
177 ResourceStringTables
.insert(new(pai_symbol
,initname_global('FPC_RESOURCESTRINGTABLES',0)));
178 ResourceStringTables
.concat(new(pai_symbol_end
,initname('FPC_RESOURCESTRINGTABLES')));
180 { insert in data segment }
181 if (cs_create_smart
in aktmoduleswitches
) then
182 datasegment
^.concat(new(pai_cut
,init
));
183 datasegment
^.concatlist(@ResourceStringTables
);
184 ResourceStringTables
.done
;
188 procedure InsertInitFinalTable
;
191 unitinits
: taasmoutput
;
196 hp
:=pused_unit(usedunits
.first
);
197 while assigned(hp
) do
199 { call the unit init code and make it external }
200 if (hp
^.u
^.flags
and (uf_init
or uf_finalize
))<>0 then
202 if (hp
^.u
^.flags
and uf_init
)<>0 then
204 unitinits
.concat(new(pai_const_symbol
,initname('INIT$$'+hp
^.u
^.modulename
^)));
207 unitinits
.concat(new(pai_const
,init_32bit(0)));
208 if (hp
^.u
^.flags
and uf_finalize
)<>0 then
210 unitinits
.concat(new(pai_const_symbol
,initname('FINALIZE$$'+hp
^.u
^.modulename
^)));
213 unitinits
.concat(new(pai_const
,init_32bit(0)));
216 hp
:=Pused_unit(hp
^.next
);
218 if current_module
^.islibrary
then
219 if (current_module
^.flags
and uf_finalize
)<>0 then
221 { INIT code is done by PASCALMAIN calling }
222 unitinits
.concat(new(pai_const
,init_32bit(0)));
223 unitinits
.concat(new(pai_const_symbol
,initname('FINALIZE$$'+current_module
^.modulename
^)));
226 { TableCount,InitCount }
227 unitinits
.insert(new(pai_const
,init_32bit(0)));
228 unitinits
.insert(new(pai_const
,init_32bit(count
)));
229 unitinits
.insert(new(pai_symbol
,initname_global('INITFINAL',0)));
230 unitinits
.concat(new(pai_symbol_end
,initname('INITFINAL')));
231 { insert in data segment }
232 if (cs_create_smart
in aktmoduleswitches
) then
233 datasegment
^.concat(new(pai_cut
,init
));
234 datasegment
^.concatlist(@unitinits
);
239 procedure insertheap
;
241 if (cs_create_smart
in aktmoduleswitches
) then
243 bsssegment
^.concat(new(pai_cut
,init
));
244 datasegment
^.concat(new(pai_cut
,init
));
246 { On the Macintosh Classic M68k Architecture
247 The Heap variable is simply a POINTER to the
248 real HEAP. The HEAP must be set up by the RTL
249 and must store the pointer in this value.
250 On OS/2 the heap is also intialized by the RTL. We do
251 not output a pointer }
252 case target_info
.target
of
262 target_powerpc_linux
:
267 bsssegment
^.concat(new(pai_datablock
,init_global('HEAP',4)));
272 bsssegment
^.concat(new(pai_datablock
,init_global('HEAP',heapsize
)));
275 if target_info
.target
<>target_m68k_PalmOS
then
277 datasegment
^.concat(new(pai_symbol
,initname_global('HEAP_SIZE',0)));
278 datasegment
^.concat(new(pai_const
,init_32bit(heapsize
)));
281 datasegment
^.concat(new(pai_symbol
,initname_global('HEAPSIZE',4)));
282 datasegment
^.concat(new(pai_const
,init_32bit(heapsize
)));
287 procedure inserttargetspecific
;
289 case target_info
.target
of
295 target_powerpc_linux
:
301 { stacksize can be specified }
302 datasegment
^.concat(new(pai_symbol
,initname_global('__stklen',4)));
303 datasegment
^.concat(new(pai_const
,init_32bit(stacksize
)));
309 { stacksize can be specified }
310 datasegment
^.concat(new(pai_symbol
,initname_global('__stklen',4)));
311 datasegment
^.concat(new(pai_const
,init_32bit(stacksize
)));
318 function loadunit(const s
: string;compile_system
:boolean) : pmodule
;forward;
321 procedure load_usedunits(compile_system
:boolean);
324 loaded_unit
: pmodule
;
326 nextmapentry
: longint;
330 new(current_module
^.map
);
331 fillchar(current_module
^.map
^,sizeof(tunitmap
),#0);
333 current_module
^.map
^[0]:=current_module
;
336 { load the used units from interface }
337 current_module
^.in_implementation
:=false;
338 pu
:=pused_unit(current_module
^.used_units
.first
);
339 while assigned(pu
) do
341 if (not pu
^.loaded
) and (pu
^.in_interface
) then
343 loaded_unit
:=loadunit(pu
^.name
^,false);
344 if current_module
^.compiled
then
346 { register unit in used units }
349 { doubles are not important for that list PM }
350 pu
^.u
^.dependent_units
.concat(new(pdependent_unit
,init(current_module
)));
351 { need to recompile the current unit ? }
352 if loaded_unit
^.crc
<>pu
^.checksum
then
354 Message2(unit_u_recompile_crc_change
,current_module
^.modulename
^,pu
^.name
^);
355 current_module
^.recompile_reason
:=rr_crcchanged
;
356 current_module
^.do_compile
:=true;
357 dispose(current_module
^.map
);
358 current_module
^.map
:=nil;
361 { setup the map entry for deref }
363 current_module
^.map
^[nextmapentry
]:=loaded_unit
^.globalsymtable
;
365 current_module
^.map
^[nextmapentry
]:=loaded_unit
;
368 if nextmapentry
>maxunits
then
369 Message(unit_f_too_much_units
);
371 pu
:=pused_unit(pu
^.next
);
373 { ok, now load the unit }
374 current_module
^.globalsymtable
:=new(punitsymtable
,loadasunit
);
375 { now only read the implementation part }
376 current_module
^.in_implementation
:=true;
377 { load the used units from implementation }
378 pu
:=pused_unit(current_module
^.used_units
.first
);
379 while assigned(pu
) do
381 if (not pu
^.loaded
) and (not pu
^.in_interface
) then
383 loaded_unit
:=loadunit(pu
^.name
^,false);
384 if current_module
^.compiled
then
386 { register unit in used units }
389 { need to recompile the current unit ? }
390 if (loaded_unit
^.interface_crc
<>pu
^.interface_checksum
) {and
391 not(current_module^.in_second_compile) } then
393 Message2(unit_u_recompile_crc_change
,current_module
^.modulename
^,pu
^.name
^+' {impl}');
394 current_module
^.recompile_reason
:=rr_crcchanged
;
395 current_module
^.do_compile
:=true;
396 dispose(current_module
^.map
);
397 current_module
^.map
:=nil;
400 { setup the map entry for deref }
402 current_module
^.map
^[nextmapentry
]:=loaded_unit
^.globalsymtable
;
404 current_module
^.map
^[nextmapentry
]:=loaded_unit
;
407 if nextmapentry
>maxunits
then
408 Message(unit_f_too_much_units
);
410 pu
:=pused_unit(pu
^.next
);
412 { load browser info if stored }
413 if ((current_module
^.flags
and uf_has_browser
)<>0) and load_refs
then
414 punitsymtable(current_module
^.globalsymtable
)^.load_symtable_refs
;
415 { remove the map, it's not needed anymore }
416 dispose(current_module
^.map
);
417 current_module
^.map
:=nil;
421 function loadunit(const s
: string;compile_system
:boolean) : pmodule
;
423 ImplIntf
: array[boolean] of string[15]=('interface','implementation');
426 second_time
: boolean;
427 old_current_ppu
: pppufile
;
428 old_current_module
,hp
,hp2
: pmodule
;
429 name
: string;{ necessary because current_module^.mainsource^ is reset in compile !! }
430 scanner
: pscannerfile
;
432 procedure loadppufile
;
434 { load interface section }
435 if not current_module
^.do_compile
then
437 { only load units when we don't recompile }
438 if not current_module
^.do_compile
then
439 load_usedunits(compile_system
);
441 if current_module
^.do_compile
then
443 { we don't need the ppufile anymore }
444 if assigned(current_module
^.ppufile
) then
446 dispose(current_module
^.ppufile
,done
);
447 current_module
^.ppufile
:=nil;
450 { recompile the unit or give a fatal error if sources not available }
451 if not(current_module
^.sources_avail
) and
452 not(current_module
^.sources_checked
) then
453 if (not current_module
^.search_unit(current_module
^.modulename
^,true))
454 and (length(current_module
^.modulename
^)>8) then
455 current_module
^.search_unit(copy(current_module
^.modulename
^,1,8),true);
456 if not(current_module
^.sources_avail
) then
459 current_module
:=old_current_module
;
460 if hp
^.recompile_reason
=rr_noppu
then
461 Message1(unit_f_cant_find_ppu
,hp
^.modulename
^)
463 Message1(unit_f_cant_compile_unit
,hp
^.modulename
^);
468 if current_module
^.in_compile
then
470 current_module
^.in_second_compile
:=true;
471 Message1(parser_d_compiling_second_time
,current_module
^.modulename
^);
473 current_scanner
^.tempcloseinputfile
;
474 name
:=current_module
^.mainsource
^;
475 if assigned(scanner
) then
476 scanner
^.invalid
:=true;
477 compile(name
,compile_system
);
478 current_module
^.in_second_compile
:=false;
479 if (not current_scanner
^.invalid
) then
480 current_scanner
^.tempopeninputfile
;
485 { only reassemble ? }
486 if (current_module
^.do_assemble
) then
489 if assigned(current_module
^.ppufile
) then
491 dispose(current_module
^.ppufile
,done
);
492 current_module
^.ppufile
:=nil;
501 old_current_module
:=current_module
;
502 old_current_ppu
:=current_ppu
;
504 Message3(unit_u_load_unit
,current_module
^.modulename
^,ImplIntf
[current_module
^.in_implementation
],s
);
508 { search all loaded units }
509 hp
:=pmodule(loaded_units
.first
);
510 while assigned(hp
) do
512 if hp
^.modulename
^=s
then
514 { forced to reload ? }
515 if hp
^.do_reload
then
517 hp
^.do_reload
:=false;
520 { the unit is already registered }
521 { and this means that the unit }
522 { is already compiled }
523 { else there is a cyclic unit use }
524 if assigned(hp
^.globalsymtable
) then
525 st
:=punitsymtable(hp
^.globalsymtable
)
528 { both units in interface ? }
529 if (not current_module
^.in_implementation
) and (not hp
^.in_implementation
) then
531 { check for a cycle }
532 hp2
:=current_module
^.loaded_from
;
533 while assigned(hp2
) and (hp2
<>hp
) do
535 if hp2
^.in_implementation
then
538 hp2
:=hp2
^.loaded_from
;
540 if assigned(hp2
) then
541 Message2(unit_f_circular_unit_reference
,current_module
^.modulename
^,hp
^.modulename
^);
546 else if copy(hp
^.modulename
^,1,8)=s
then
549 hp
:=pmodule(hp
^.next
);
551 if assigned(dummy
) and not assigned(hp
) then
552 Message2(unit_w_unit_name_error
,s
,dummy
^.modulename
^);
553 { the unit is not in the symtable stack }
554 if (not assigned(st
)) then
558 { remove the old unit }
559 loaded_units
.remove(hp
);
560 scanner
:=hp
^.scanner
;
562 hp
^.scanner
:=scanner
;
563 { try to reopen ppu }
564 hp
^.search_unit(s
,false);
565 { try to load the unit a second time first }
567 current_module
^.in_second_load
:=true;
568 Message1(unit_u_second_load_unit
,current_module
^.modulename
^);
572 { generates a new unit info record }
574 current_module
:=new(pmodule
,init(s
,true));
578 current_ppu
:=current_module
^.ppufile
;
579 { close old_current_ppu on system that are
580 short on file handles like DOS PM }
581 {$ifdef SHORT_ON_FILE_HANDLES}
582 if assigned(old_current_ppu
) then
583 old_current_ppu
^.tempclose
;
584 {$endif SHORT_ON_FILE_HANDLES}
585 { now we can register the unit }
586 current_module
^.loaded_from
:=old_current_module
;
587 loaded_units
.insert(current_module
);
588 { now realy load the ppu }
590 { set compiled flag }
591 current_module
^.compiled
:=true;
592 { load return pointer }
594 { for a second_time recompile reload all dependent units,
595 for a first time compile register the unit _once_ }
598 { now reload all dependent units }
599 hp2
:=pmodule(loaded_units
.first
);
600 while assigned(hp2
) do
602 if hp2
^.do_reload
then
603 dummy
:=loadunit(hp2
^.modulename
^,false);
604 hp2
:=pmodule(hp2
^.next
);
608 usedunits
.concat(new(pused_unit
,init(current_module
,true)));
610 { set the old module }
611 {$ifdef SHORT_ON_FILE_HANDLES}
612 if assigned(old_current_ppu
) then
613 old_current_ppu
^.tempopen
;
614 {$endif SHORT_ON_FILE_HANDLES}
615 current_ppu
:=old_current_ppu
;
616 current_module
:=old_current_module
;
621 procedure loaddefaultunits
;
626 { are we compiling the system unit? }
627 if (cs_compilesystem
in aktmoduleswitches
) then
629 { create system defines }
631 { we don't need to reset anything, it's already done in parser.pas }
634 { insert the system unit, it is allways the first }
635 hp
:=loadunit(upper(target_info
.system_unit
),true);
636 systemunit
:=hp
^.globalsymtable
;
637 { it's always the first unit }
638 systemunit
^.next
:=nil;
639 symtablestack
:=systemunit
;
640 { add to the used units }
641 current_module
^.used_units
.concat(new(pused_unit
,init(hp
,true)));
642 unitsym
:=new(punitsym
,init('SYSTEM',systemunit
));
644 refsymtable
^.insert(unitsym
);
645 { read default constant definitions }
648 { if POWER is defined in the RTL then use it for starstar overloading }
649 {$ifdef DONOTCHAINOPERATORS}
650 getsym('POWER',false);
651 {$endif DONOTCHAINOPERATORS}
653 {$ifdef DONOTCHAINOPERATORS}
654 { Code now in chainoperators PM }
655 if assigned(srsym
) and (srsym
^.typ
=procsym
) and (overloaded_operators
[_STARSTAR
]=nil) then
656 overloaded_operators
[_STARSTAR
]:=pprocsym(srsym
);
657 {$endif DONOTCHAINOPERATORS}
659 if m_objpas
in aktmodeswitches
then
661 hp
:=loadunit('OBJPAS',false);
662 psymtable(hp
^.globalsymtable
)^.next
:=symtablestack
;
663 symtablestack
:=hp
^.globalsymtable
;
664 { add to the used units }
665 current_module
^.used_units
.concat(new(pused_unit
,init(hp
,true)));
666 unitsym
:=new(punitsym
,init('OBJPAS',hp
^.globalsymtable
));
668 refsymtable
^.insert(unitsym
);
670 { Profile unit? Needed for go32v2 only }
671 if (cs_profile
in aktmoduleswitches
) and (target_info
.target
=target_i386_go32v2
) then
673 hp
:=loadunit('PROFILE',false);
674 psymtable(hp
^.globalsymtable
)^.next
:=symtablestack
;
675 symtablestack
:=hp
^.globalsymtable
;
676 { add to the used units }
677 current_module
^.used_units
.concat(new(pused_unit
,init(hp
,true)));
678 unitsym
:=new(punitsym
,init('PROFILE',hp
^.globalsymtable
));
680 refsymtable
^.insert(unitsym
);
682 { Units only required for main module }
683 if not(current_module
^.is_unit
) then
686 if (cs_gdb_heaptrc
in aktglobalswitches
) then
688 hp
:=loadunit('HEAPTRC',false);
689 psymtable(hp
^.globalsymtable
)^.next
:=symtablestack
;
690 symtablestack
:=hp
^.globalsymtable
;
691 { add to the used units }
692 current_module
^.used_units
.concat(new(pused_unit
,init(hp
,true)));
693 unitsym
:=new(punitsym
,init('HEAPTRC',hp
^.globalsymtable
));
695 refsymtable
^.insert(unitsym
);
698 if (cs_gdb_lineinfo
in aktglobalswitches
) then
700 hp
:=loadunit('LINEINFO',false);
701 psymtable(hp
^.globalsymtable
)^.next
:=symtablestack
;
702 symtablestack
:=hp
^.globalsymtable
;
703 { add to the used units }
704 current_module
^.used_units
.concat(new(pused_unit
,init(hp
,true)));
705 unitsym
:=new(punitsym
,init('LINEINFO',hp
^.globalsymtable
));
707 refsymtable
^.insert(unitsym
);
710 { save default symtablestack }
711 defaultsymtablestack
:=symtablestack
;
725 oldprocsym
:=aktprocsym
;
733 { Give a warning if objpas is loaded }
735 Message(parser_w_no_objpas_use_mode
);
736 { check if the unit is already used }
737 pu
:=pused_unit(current_module
^.used_units
.first
);
738 while assigned(pu
) do
740 if (pu
^.name
^=s
) then
742 pu
:=pused_unit(pu
^.next
);
744 { avoid uses of itself }
745 if not assigned(pu
) and (s
<>current_module
^.modulename
^) then
748 hp2
:=loadunit(s
,false);
749 { the current module uses the unit hp2 }
750 current_module
^.used_units
.concat(new(pused_unit
,init(hp2
,not current_module
^.in_implementation
)));
751 pused_unit(current_module
^.used_units
.last
)^.in_uses
:=true;
752 if current_module
^.compiled
then
754 unitsym
:=new(punitsym
,init(s
,hp2
^.globalsymtable
));
755 { never claim about unused unit if
756 there is init or finalize code PM }
757 if (hp2
^.flags
and (uf_init
or uf_finalize
))<>0 then
759 refsymtable
^.insert(unitsym
);
762 Message1(sym_e_duplicate_id
,s
);
773 { set the symtable to systemunit so it gets reorderd correctly }
774 symtablestack
:=defaultsymtablestack
;
776 { now insert the units in the symtablestack }
777 hp
:=pused_unit(current_module
^.used_units
.first
);
778 while assigned(hp
) do
781 if (cs_debuginfo
in aktmoduleswitches
) and
782 (cs_gdb_dbx
in aktglobalswitches
) and
783 not hp
^.is_stab_written
then
785 punitsymtable(hp
^.u
^.globalsymtable
)^.concattypestabto(debuglist
);
786 hp
^.is_stab_written
:=true;
787 hp
^.unitid
:=psymtable(hp
^.u
^.globalsymtable
)^.unitid
;
793 while assigned(hp3
) do
795 { insert units only once ! }
796 if hp
^.u
^.globalsymtable
=hp3
then
799 { unit isn't inserted }
802 psymtable(hp
^.u
^.globalsymtable
)^.next
:=symtablestack
;
803 symtablestack
:=psymtable(hp
^.u
^.globalsymtable
);
804 {$ifdef CHAINPROCSYMS}
805 symtablestack
^.chainprocsyms
;
806 {$endif CHAINPROCSYMS}
813 hp
:=pused_unit(hp
^.next
);
815 aktprocsym
:=oldprocsym
;
819 procedure write_gdb_info
;
824 if not (cs_debuginfo
in aktmoduleswitches
) then
826 if (cs_gdb_dbx
in aktglobalswitches
) then
828 debuglist
^.concat(new(pai_asm_comment
,init(strpnew('EINCL of global '+
829 punitsymtable(current_module
^.globalsymtable
)^.name
^+' has index '+
830 tostr(punitsymtable(current_module
^.globalsymtable
)^.unitid
)))));
831 debuglist
^.concat(new(pai_stabs
,init(strpnew('"'+
832 punitsymtable(current_module
^.globalsymtable
)^.name
^+'",'+
833 tostr(N_EINCL
)+',0,0,0'))));
834 punitsymtable(current_module
^.globalsymtable
)^.dbx_count_ok
:={true}false;
835 dbx_counter
:=punitsymtable(current_module
^.globalsymtable
)^.prev_dbx_counter
;
839 { now insert the units in the symtablestack }
840 hp
:=pused_unit(current_module
^.used_units
.first
);
841 while assigned(hp
) do
843 if (cs_debuginfo
in aktmoduleswitches
) and
844 not hp
^.is_stab_written
then
846 punitsymtable(hp
^.u
^.globalsymtable
)^.concattypestabto(debuglist
);
847 hp
^.is_stab_written
:=true;
848 hp
^.unitid
:=psymtable(hp
^.u
^.globalsymtable
)^.unitid
;
850 hp
:=pused_unit(hp
^.next
);
852 if current_module
^.in_implementation
and
853 assigned(current_module
^.localsymtable
) then
856 punitsymtable(current_module
^.localsymtable
)^.concattypestabto(debuglist
);
857 { and all local symbols}
858 punitsymtable(current_module
^.localsymtable
)^.concatstabto(debuglist
);
860 else if assigned(current_module
^.globalsymtable
) then
863 punitsymtable(current_module
^.globalsymtable
)^.concattypestabto(debuglist
);
864 { and all local symbols}
865 punitsymtable(current_module
^.globalsymtable
)^.concatstabto(debuglist
);
874 procedure parse_implementation_uses(symt
:Psymtable
);
878 symt
^.symtabletype
:=unitsymtable
;
880 symt
^.symtabletype
:=globalsymtable
;
888 procedure setupglobalswitches
;
890 procedure def_symbol(const s
:string);
894 mac
:=new(pmacrosym
,init(s
));
896 Message1(parser_m_macro_defined
,mac
^.name
);
901 { can't have local browser when no global browser }
902 if (cs_local_browser
in aktmoduleswitches
) and
903 not(cs_browser
in aktmoduleswitches
) then
904 exclude(aktmoduleswitches
,cs_local_browser
);
906 { define a symbol in delphi,objfpc,tp,gpc mode }
907 if (m_delphi
in aktmodeswitches
) then
908 def_symbol('FPC_DELPHI')
910 if (m_tp
in aktmodeswitches
) then
913 if (m_objfpc
in aktmodeswitches
) then
914 def_symbol('FPC_OBJFPC')
916 if (m_gpc
in aktmodeswitches
) then
917 def_symbol('FPC_GPC');
921 procedure gen_main_procsym(const name
:string;options
:tproctypeoption
;st
:psymtable
);
925 {Generate a procsym for main}
927 aktprocsym
:=new(Pprocsym
,init(name
));
928 { main are allways used }
929 inc(aktprocsym
^.refs
);
930 {Try to insert in in static symtable ! }
933 aktprocsym
^.definition
:=new(Pprocdef
,init
);
935 aktprocsym
^.definition
^.proctypeoption
:=options
;
936 aktprocsym
^.definition
^.setmangledname(target_os
.cprefix
+name
);
937 aktprocsym
^.definition
^.forwarddef
:=false;
939 { The localst is a local symtable. Change it into the static
941 dispose(aktprocsym
^.definition
^.localst
,done
);
942 aktprocsym
^.definition
^.localst
:=st
;
943 { and insert the procsym in symtable }
944 st
^.insert(aktprocsym
);
945 { set some informations about the main program }
948 returntype
.setdef(voiddef
);
951 framepointer
:=frame_pointer
;
959 function is_assembler_generated
:boolean;
961 is_assembler_generated
:=(Errorcount
=0) and
963 codesegment
^.empty
and
964 datasegment
^.empty
and
965 bsssegment
^.empty
and
966 ((importssection
=nil) or importssection
^.empty
) and
967 ((resourcesection
=nil) or resourcesection
^.empty
) and
968 ((resourcestringlist
=nil) or resourcestringlist
^.empty
)
973 main_file
: pinputfile
;
974 {$ifdef fixLeaksOnError}
975 names
: Pstringcontainer
;
976 {$else fixLeaksOnError}
977 names
: Tstringcontainer
;
978 {$endif fixLeaksOnError}
980 unitst
: punitsymtable
;
984 {$ifndef Dont_use_double_checksum}
985 store_crc
,store_interface_crc
: longint;
987 s1
,s2
: ^string; {Saves stack space}
988 force_init_final
: boolean;
992 if Compile_Level
=1 then
997 { create filenames and unit name }
998 main_file
:= current_scanner
^.inputfile
;
999 while assigned(main_file
^.next
) do
1000 main_file
:= main_file
^.next
;
1002 current_module
^.SetFileName(main_file
^.path
^+main_file
^.name
^,true);
1004 stringdispose(current_module
^.modulename
);
1005 current_module
^.modulename
:=stringdup(upper(pattern
));
1006 { check for system unit }
1009 s1
^:=upper(target_info
.system_unit
);
1010 s2
^:=upper(SplitName(main_file
^.name
^));
1011 if (cs_compilesystem
in aktmoduleswitches
) then
1013 if ((length(current_module
^.modulename
^)>8) or
1014 ((current_module
^.modulename
^<>s1
^) and
1015 (current_module
^.modulename
^<>'SYSTEM')) or
1016 (current_module
^.modulename
^<>s2
^)) then
1017 Message1(unit_e_illegal_unit_name
,current_module
^.modulename
^);
1021 if (cs_check_unit_name
in aktglobalswitches
) and
1022 not((current_module
^.modulename
^=s2
^) or
1023 ((length(current_module
^.modulename
^)>8) and
1024 (copy(current_module
^.modulename
^,1,8)=s2
^))) then
1025 Message1(unit_e_illegal_unit_name
,current_module
^.modulename
^);
1026 if (current_module
^.modulename
^=s1
^) then
1027 Message(unit_w_switch_us_missed
);
1034 consume(_SEMICOLON
);
1035 consume(_INTERFACE
);
1036 { global switches are read, so further changes aren't allowed }
1037 current_module
^.in_global
:=false;
1039 { handle the global switches }
1040 setupglobalswitches
;
1042 Message1(unit_u_start_parse_interface
,current_module
^.modulename
^);
1045 status
.currentmodule
:=current_module
^.modulename
^;
1047 { maybe turn off m_objpas if we are compiling objpas }
1048 if (current_module
^.modulename
^='OBJPAS') then
1049 aktmodeswitches
:=aktmodeswitches
-[m_objpas
];
1051 { this should be placed after uses !!}
1052 {$ifndef UseNiceNames}
1053 procprefix
:='_'+current_module
^.modulename
^+'$$';
1054 {$else UseNiceNames}
1055 procprefix
:='_'+tostr(length(current_module
^.modulename
^))+lowercase(current_module
^.modulename
^)+'_';
1056 {$endif UseNiceNames}
1060 { generate now the global symboltable }
1061 st
:=new(punitsymtable
,init(globalsymtable
,current_module
^.modulename
^));
1063 unitst
:=punitsymtable(st
);
1064 { define first as local to overcome dependency conflicts }
1065 current_module
^.localsymtable
:=st
;
1067 { the unit name must be usable as a unit specifier }
1068 { inside the unit itself (PM) }
1069 { this also forbids to have another symbol }
1070 { with the same name as the unit }
1071 refsymtable
^.insert(new(punitsym
,init(current_module
^.modulename
^,unitst
)));
1073 { a unit compiled at command line must be inside the loaded_unit list }
1074 if (compile_level
=1) then
1075 loaded_units
.insert(current_module
);
1077 { load default units, like the system unit }
1084 { insert qualifier for the system unit (allows system.writeln) }
1085 if not(cs_compilesystem
in aktmoduleswitches
) then
1089 unitst
^.symtabletype
:=unitsymtable
;
1091 { has it been compiled at a higher level ?}
1092 if current_module
^.compiled
then
1094 { this unit symtable is obsolete }
1095 { dispose(unitst,done);
1096 disposed as localsymtable !! }
1100 unitst
^.symtabletype
:=globalsymtable
;
1102 { ... but insert the symbol table later }
1103 st
^.next
:=symtablestack
;
1107 { while compiling a system unit, some types are directly inserted }
1109 st
^.next
:=symtablestack
;
1111 insert_intern_types(st
);
1114 { now we know the place to insert the constants }
1115 constsymtable
:=symtablestack
;
1117 { move the global symtab from the temporary local to global }
1118 current_module
^.globalsymtable
:=current_module
^.localsymtable
;
1119 current_module
^.localsymtable
:=nil;
1123 { number all units, so we know if a unit is used by this unit or
1124 needs to be added implicitly }
1127 { ... parse the declarations }
1128 Message1(parser_u_parsing_interface
,current_module
^.modulename
^);
1129 read_interface_declarations
;
1131 { leave when we got an error }
1132 if (Errorcount
>0) and not status
.skip_error
then
1134 Message1(unit_f_errors_in_unit
,tostr(Errorcount
));
1135 status
.skip_error
:=true;
1138 {else in inteface its somatimes necessary even if unused
1143 {$endIf Def New_GDB}
1145 {$ifndef Dont_use_double_checksum}
1146 if not(cs_compilesystem
in aktmoduleswitches
) then
1147 if (Errorcount
=0) then
1148 writeunitas(current_module
^.ppufilename
^,punitsymtable(symtablestack
),true);
1149 {$endif Test_Double_checksum}
1151 { Parse the implementation section }
1152 consume(_IMPLEMENTATION
);
1153 current_module
^.in_implementation
:=true;
1154 Message1(unit_u_start_parse_implementation
,current_module
^.modulename
^);
1158 { generates static symbol table }
1159 st
:=new(punitsymtable
,init(staticsymtable
,current_module
^.modulename
^));
1160 current_module
^.localsymtable
:=st
;
1162 { remove the globalsymtable from the symtable stack }
1163 { to reinsert it after loading the implementation units }
1164 symtablestack
:=unitst
^.next
;
1166 { we don't want implementation units symbols in unitsymtable !! PM }
1169 { Read the implementation units }
1170 parse_implementation_uses(unitst
);
1172 if current_module
^.compiled
then
1178 { reset ranges/stabs in exported definitions }
1181 { All units are read, now give them a number }
1184 { now we can change refsymtable }
1187 { but reinsert the global symtable as lasts }
1188 unitst
^.next
:=symtablestack
;
1189 symtablestack
:=unitst
;
1191 {$ifndef DONOTCHAINOPERATORS}
1192 symtablestack
^.chainoperators
;
1193 {$endif DONOTCHAINOPERATORS}
1198 constsymtable
:=symtablestack
;
1204 allow_special
:=true;
1205 Switch_to_temp_heap
;
1207 { it will report all crossings }
1208 allow_special
:=false;
1211 Message1(parser_u_parsing_implementation
,current_module
^.modulename
^);
1213 { Compile the unit }
1214 codegen_newprocedure
;
1215 gen_main_procsym(current_module
^.modulename
^+'_init',potype_unitinit
,st
);
1216 {$ifdef fixLeaksOnError}
1218 strContStack
.push(names
);
1219 names
^.insert('INIT$$'+current_module
^.modulename
^);
1220 names
^.insert(target_os
.cprefix
+current_module
^.modulename
^+'_init');
1221 compile_proc_body(names
^,true,false);
1222 if names
<> PstringContainer(strContStack
.pop
) then
1223 writeln('Problem with strContStack in pmodules (1)');
1224 dispose(names
,done
);
1225 {$else fixLeaksOnError}
1227 names
.insert('INIT$$'+current_module
^.modulename
^);
1228 names
.insert(target_os
.cprefix
+current_module
^.modulename
^+'_init');
1229 compile_proc_body(names
,true,false);
1231 {$endif fixLeaksOnError}
1232 codegen_doneprocedure
;
1234 { avoid self recursive destructor call !! PM }
1235 aktprocsym
^.definition
^.localst
:=nil;
1237 { if the unit contains ansi/widestrings, initialization and
1238 finalization code must be forced }
1239 force_init_final
:=needs_init_final(current_module
^.globalsymtable
)
1240 or needs_init_final(current_module
^.localsymtable
);
1242 { should we force unit initialization? }
1243 { this is a hack, but how can it be done better ? }
1244 if force_init_final
and ((current_module
^.flags
and uf_init
)=0) then
1246 current_module
^.flags
:=current_module
^.flags
or uf_init
;
1247 { now we can insert a cut }
1248 if (cs_create_smart
in aktmoduleswitches
) then
1249 codesegment
^.concat(new(pai_cut
,init
));
1250 genimplicitunitinit(codesegment
);
1253 if token
=_FINALIZATION
then
1255 { set module options }
1256 current_module
^.flags
:=current_module
^.flags
or uf_finalize
;
1258 { Compile the finalize }
1259 codegen_newprocedure
;
1260 gen_main_procsym(current_module
^.modulename
^+'_finalize',potype_unitfinalize
,st
);
1261 {$ifdef fixLeaksOnError}
1263 strContStack
.push(names
);
1264 names
^.insert('FINALIZE$$'+current_module
^.modulename
^);
1265 names
^.insert(target_os
.cprefix
+current_module
^.modulename
^+'_finalize');
1266 compile_proc_body(names
^,true,false);
1267 if names
<> PstringContainer(strContStack
.pop
) then
1268 writeln('Problem with strContStack in pmodules (2)');
1269 dispose(names
,done
);
1270 {$else fixLeaksOnError}
1272 names
.insert('FINALIZE$$'+current_module
^.modulename
^);
1273 names
.insert(target_os
.cprefix
+current_module
^.modulename
^+'_finalize');
1274 compile_proc_body(names
,true,false);
1276 {$endif fixLeaksOnError}
1277 codegen_doneprocedure
;
1279 else if force_init_final
then
1281 current_module
^.flags
:=current_module
^.flags
or uf_finalize
;
1282 { now we can insert a cut }
1283 if (cs_create_smart
in aktmoduleswitches
) then
1284 codesegment
^.concat(new(pai_cut
,init
));
1285 genimplicitunitfinal(codesegment
);
1288 { the last char should always be a point }
1291 If ResourceStrings
^.ResStrCount
>0 then
1293 ResourceStrings
^.CreateResourceStringList
;
1294 current_module
^.flags
:=current_module
^.flags
or uf_has_resources
;
1295 { only write if no errors found }
1296 if (Errorcount
=0) then
1297 ResourceStrings
^.WriteResourceFile(Current_module
^.ModuleName
^);
1300 { avoid self recursive destructor call !! PM }
1301 aktprocsym
^.definition
^.localst
:=nil;
1302 { absence does not matter here !! }
1303 aktprocsym
^.definition
^.forwarddef
:=false;
1304 { test static symtable }
1305 if (Errorcount
=0) then
1309 st
^.allprivatesused
;
1312 { size of the static data }
1313 datasize
:=st
^.datasize
;
1316 { add all used definitions even for implementation}
1317 if (cs_debuginfo
in aktmoduleswitches
) then
1320 if assigned(current_module
^.globalsymtable
) then
1323 punitsymtable(current_module
^.globalsymtable
)^.concattypestabto(debuglist
);
1324 { and all local symbols}
1325 punitsymtable(current_module
^.globalsymtable
)^.concatstabto(debuglist
);
1328 punitsymtable(st
)^.concattypestabto(debuglist
);
1329 { and all local symbols}
1330 st
^.concatstabto(debuglist
);
1333 {$endIf Def New_GDB}
1339 { tests, if all (interface) forwards are resolved }
1340 if (Errorcount
=0) then
1342 symtablestack
^.check_forwards
;
1343 symtablestack
^.allprivatesused
;
1346 { now we have a correct unit, change the symtable type }
1347 current_module
^.in_implementation
:=false;
1348 symtablestack
^.symtabletype
:=unitsymtable
;
1350 punitsymtable(symtablestack
)^.is_stab_written
:=false;
1353 { leave when we got an error }
1354 if (Errorcount
>0) and not status
.skip_error
then
1356 Message1(unit_f_errors_in_unit
,tostr(Errorcount
));
1357 status
.skip_error
:=true;
1362 { generate imports }
1363 if current_module
^.uses_imports
then
1364 importlib
^.generatelib
;
1366 { insert own objectfile, or say that it's in a library
1367 (no check for an .o when loading) }
1368 if is_assembler_generated
then
1371 current_module
^.flags
:=current_module
^.flags
or uf_no_link
;
1373 if cs_local_browser
in aktmoduleswitches
then
1374 current_module
^.localsymtable
:=refsymtable
;
1375 { Write out the ppufile }
1376 {$ifndef Dont_use_double_checksum}
1377 store_interface_crc
:=current_module
^.interface_crc
;
1378 store_crc
:=current_module
^.crc
;
1379 {$endif Test_Double_checksum}
1380 if (Errorcount
=0) then
1381 writeunitas(current_module
^.ppufilename
^,punitsymtable(symtablestack
),false);
1383 {$ifndef Dont_use_double_checksum}
1384 if not(cs_compilesystem
in aktmoduleswitches
) then
1385 if store_interface_crc
<>current_module
^.interface_crc
then
1386 Comment(V_Warning
,current_module
^.ppufilename
^+' Interface CRC changed '+
1387 tostr(store_crc
)+'<>'+tostr(current_module
^.interface_crc
));
1389 if not(cs_compilesystem
in aktmoduleswitches
) then
1390 if (store_crc
<>current_module
^.crc
) and simplify_ppu
then
1391 Comment(V_Warning
,current_module
^.ppufilename
^+' implementation CRC changed '+
1392 tostr(store_crc
)+'<>'+tostr(current_module
^.interface_crc
));
1394 {$endif ndef Dont_use_Double_checksum}
1395 { must be done only after local symtable ref stores !! }
1398 pu
:=pused_unit(usedunits
.first
);
1399 while assigned(pu
) do
1401 if assigned(pu
^.u
^.globalsymtable
) then
1402 punitsymtable(pu
^.u
^.globalsymtable
)^.is_stab_written
:=false;
1403 pu
:=pused_unit(pu
^.next
);
1407 { remove static symtable (=refsymtable) here to save some mem }
1408 if not (cs_local_browser
in aktmoduleswitches
) then
1411 current_module
^.localsymtable
:=nil;
1417 if is_assembler_generated
then
1419 { finish asmlist by adding segment starts }
1425 { leave when we got an error }
1426 if (Errorcount>0) and not status.skip_error then
1428 Message1(unit_f_errors_in_unit,tostr(Errorcount));
1429 status.skip_error:=true;
1435 procedure proc_program(islibrary : boolean);
1437 main_file: pinputfile;
1440 {$ifdef fixLeaksOnError}
1441 names : Pstringcontainer;
1442 {$else fixLeaksOnError}
1443 names : Tstringcontainer;
1444 {$endif fixLeaksOnError}
1446 DLLsource:=islibrary;
1447 Compiler.IsLibrary:=IsLibrary;
1450 { relocation works only without stabs under win32 !! PM }
1451 { internal assembler uses rva for stabs info
1452 so it should work with relocated DLLs }
1454 (target_info.target=target_i386_win32) and
1455 (target_info.assem<>as_i386_pecoff) then
1457 aktglobalswitches:=aktglobalswitches+[cs_link_strip];
1458 { Warning stabs info does not work with reloc section !! }
1459 if cs_debuginfo in aktmoduleswitches then
1461 Message1(parser_w_parser_reloc_no_debug,current_module^.mainsource^);
1462 Message(parser_w_parser_win32_debug_needs_WN);
1463 aktmoduleswitches:=aktmoduleswitches-[cs_debuginfo];
1467 { get correct output names }
1468 main_file := current_scanner^.inputfile;
1469 while assigned(main_file^.next) do
1470 main_file := main_file^.next;
1472 current_module^.SetFileName(main_file^.path^+main_file^.name^,true);
1477 stringdispose(current_module^.modulename);
1478 current_module^.modulename:=stringdup(pattern);
1479 current_module^.islibrary:=true;
1480 exportlib^.preparelib(pattern);
1482 consume(_SEMICOLON);
1485 { is there an program head ? }
1486 if token=_PROGRAM then
1489 stringdispose(current_module^.modulename);
1490 current_module^.modulename:=stringdup(pattern);
1491 if (target_info.target=target_i386_WIN32) then
1492 exportlib^.preparelib(pattern);
1494 if token=_LKLAMMER then
1500 consume(_SEMICOLON);
1502 else if (target_info.target=target_i386_WIN32) then
1503 exportlib^.preparelib(current_module^.modulename^);
1505 { global switches are read, so further changes aren't allowed }
1506 current_module^.in_global:=false;
1508 { setup things using the global switches }
1509 setupglobalswitches;
1511 { set implementation flag }
1512 current_module^.in_implementation:=true;
1514 { insert after the unit symbol tables the static symbol table }
1516 st:=new(punitsymtable,init(staticsymtable,current_module^.modulename^));
1517 current_module^.localsymtable:=st;
1521 { necessary for browser }
1522 loaded_units.insert(current_module);
1524 { load standard units (system,objpas,profile unit) }
1530 {Load the units used by the program we compile.}
1534 {$ifndef DONOTCHAINOPERATORS}
1535 symtablestack^.chainoperators;
1536 {$endif DONOTCHAINOPERATORS}
1538 { reset ranges/stabs in exported definitions }
1541 { All units are read, now give them a number }
1544 {Insert the name of the main program into the symbol table.}
1545 if current_module^.modulename^<>'' then
1546 {st^.insert(new(pprogramsym,init(current_module^.modulename^)));}
1547 st^.insert(new(punitsym,init(current_module^.modulename^,punitsymtable(st))));
1549 { ...is also constsymtable, this is the symtable where }
1550 { the elements of enumeration types are inserted }
1553 Message1(parser_u_parsing_implementation,current_module^.mainsource^);
1558 {The program intialization needs an alias, so it can be called
1559 from the bootstrap code.}
1560 codegen_newprocedure;
1561 gen_main_procsym('main',potype_proginit,st);
1562 {$ifdef fixLeaksOnError}
1564 strContStack.push(names);
1565 names^.insert('program_init');
1566 names^.insert('PASCALMAIN');
1567 names^.insert(target_os.cprefix+'main');
1569 if target_info.target=target_m68k_PalmOS then
1570 names^.insert('PilotMain');
1572 compile_proc_body(names^,true,false);
1573 if names <> PstringContainer(strContStack.pop) then
1574 writeln('Problem with strContStack in pmodules (1)');
1575 dispose(names,done);
1576 {$else fixLeaksOnError}
1578 names.insert('program_init');
1579 names.insert('PASCALMAIN');
1580 names.insert(target_os.cprefix+'main');
1582 if target_info.target=target_m68k_PalmOS then
1583 names.insert('PilotMain');
1585 compile_proc_body(names,true,false);
1587 {$endif fixLeaksOnError}
1589 { avoid self recursive destructor call !! PM }
1590 aktprocsym^.definition^.localst:=nil;
1592 { consider these symbols as global ones }
1594 current_module^.globalsymtable:=current_module^.localsymtable;
1595 current_module^.localsymtable:=nil;
1597 If ResourceStrings^.ResStrCount>0 then
1599 ResourceStrings^.CreateResourceStringList;
1600 { only write if no errors found }
1601 if (Errorcount=0) then
1602 ResourceStrings^.WriteResourceFile(Current_module^.ModuleName^);
1605 codegen_doneprocedure;
1608 if token=_FINALIZATION then
1610 { set module options }
1611 current_module^.flags:=current_module^.flags or uf_finalize;
1613 { Compile the finalize }
1614 codegen_newprocedure;
1615 gen_main_procsym(current_module^.modulename^+'_finalize',potype_unitfinalize,st);
1616 {$ifdef fixLeaksOnError}
1618 strContStack.push(names);
1619 names^.insert('FINALIZE$$'+current_module^.modulename^);
1620 names^.insert(target_os.cprefix+current_module^.modulename^+'_finalize');
1621 compile_proc_body(names^,true,false);
1622 if names <> PstringContainer(strContStack.pop) then
1623 writeln('Problem with strContStack in pmodules (1)');
1624 dispose(names,done);
1625 {$else fixLeaksOnError}
1627 names.insert('FINALIZE$$'+current_module^.modulename^);
1628 names.insert(target_os.cprefix+current_module^.modulename^+'_finalize');
1629 compile_proc_body(names,true,false);
1631 {$endif fixLeaksOnError}
1632 codegen_doneprocedure;
1635 { consume the last point }
1640 {$endIf Def New_GDB}
1641 { leave when we got an error }
1642 if (Errorcount>0) and not status.skip_error then
1644 Message1(unit_f_errors_in_unit,tostr(Errorcount));
1645 status.skip_error:=true;
1649 { test static symtable }
1650 if (Errorcount=0) then
1654 st^.allprivatesused;
1657 { generate imports }
1658 if current_module^.uses_imports then
1659 importlib^.generatelib;
1662 (target_info.target=target_i386_WIN32) then
1663 exportlib^.generatelib;
1667 insertResourceTablesTable;
1668 insertinitfinaltable;
1670 inserttargetspecific;
1672 datasize:=symtablestack^.datasize;
1674 { finish asmlist by adding segment starts }
1677 { insert own objectfile }
1680 { assemble and link }
1683 { leave when we got an error }
1684 if (Errorcount>0) and not status.skip_error then
1686 Message1(unit_f_errors_in_unit,tostr(Errorcount));
1687 status.skip_error:=true;
1691 { create the executable when we are at level 1 }
1692 if (compile_level=1) then
1694 { insert all .o files from all loaded units }
1695 hp:=pmodule(loaded_units.first);
1696 while assigned(hp) do
1698 Linker^.AddModuleFiles(hp);
1699 hp:=pmodule(hp^.next);
1702 if (cs_link_deffile in aktglobalswitches) then
1704 { finally we can create a executable }
1705 if (not current_module^.is_unit) then
1708 Linker^.MakeSharedLibrary
1710 Linker^.MakeExecutable;
1718 Revision 1.1 2002/02/19 08:22:46 sasu
1721 Revision 1.1.2.8 2000/11/19 00:20:13 pierre
1722 + set Compiler.IsLibrary
1724 Revision 1.1.2.7 2000/10/18 14:53:33 pierre
1725 * add fpc_compiled assembler local symbol
1727 Revision 1.1.2.6 2000/10/15 07:49:01 peter
1728 * Also allow system as name for the system unit, required for
1729 bootstrapping the 1.1 branch
1731 Revision 1.1.2.5 2000/09/30 16:06:33 peter
1732 * show filepos when unit can't be found
1734 Revision 1.1.2.4 2000/09/24 21:36:26 peter
1735 + setcompilemode() routine
1737 Revision 1.1.2.3 2000/08/25 08:44:25 jonas
1738 * fixed bug with include files at the very beginning of .pp/.pas files
1739 (wrong name used for generating exe/checking unit name)
1741 Revision 1.1.2.2 2000/08/21 08:09:47 pierre
1742 * fix stabs problems
1744 Revision 1.1.2.1 2000/08/18 12:48:57 pierre
1745 * generate type stabs at correct location for main file
1747 Revision 1.1 2000/07/13 06:29:54 michael
1750 Revision 1.197 2000/06/15 18:10:11 peter
1751 * first look for ppu in cwd and outputpath and after that for source
1753 * fixpath() for not linux makes path now lowercase so comparing paths
1754 with different cases (sometimes a drive letter could be
1755 uppercased) gives the expected results
1756 * sources_checked flag if there was already a full search for sources
1757 which aren't found, so another scan isn't done when checking for the
1758 sources only when recompile is needed
1760 Revision 1.196 2000/06/01 19:09:57 peter
1761 * made resourcestrings OOP so it's easier to handle it per module
1763 Revision 1.195 2000/05/11 09:40:11 pierre
1764 * some DBX changes but it still does not work !
1766 Revision 1.194 2000/05/08 13:18:09 peter
1767 * fixed setting of output names with includefile
1769 Revision 1.193 2000/05/04 20:43:33 peter
1770 * don't write rst files if errors found
1772 Revision 1.192 2000/05/03 14:39:51 pierre
1773 * Use RestoreUnitsSyms to avoid wrong hints about unused units
1774 * Avoid hints about unsused units if thet have a init or finalize code
1776 Revision 1.191 2000/04/27 11:35:03 pierre
1777 * power to ** operator fixed
1779 Revision 1.190 2000/04/26 08:54:18 pierre
1780 * More changes for operator bug
1781 Order_overloaded method removed because it conflicted with
1782 new implementation where the defs are ordered
1783 according to the unit loading order !
1785 Revision 1.189 2000/04/25 23:55:30 pierre
1786 + Hint about unused unit
1787 * Testop bug fixed !!
1788 Now the operators are only applied if the unit is explicitly loaded
1790 Revision 1.188 2000/04/14 08:15:05 pierre
1791 * close ppu file if errors
1793 Revision 1.187 2000/04/02 10:18:18 florian
1794 * bug 701 fixed: ansistrings in interface and implementation part of the units
1795 are now finalized correctly even if there are no explicit initialization/
1796 finalization statements
1798 Revision 1.186 2000/03/01 15:36:11 florian
1799 * some new stuff for the new cg
1801 Revision 1.185 2000/02/09 13:22:57 peter
1804 Revision 1.184 2000/02/06 17:20:53 peter
1805 * -gl switch for auto lineinfo including
1807 Revision 1.183 2000/01/16 22:17:12 peter
1808 * renamed call_offset to para_offset
1810 Revision 1.182 2000/01/16 14:15:33 jonas
1811 * changed "with object_type" construct because of bug in the
1814 Revision 1.181 2000/01/12 10:30:15 peter
1815 * align codesegment at the end after main proc
1817 Revision 1.180 2000/01/11 17:16:05 jonas
1818 * removed a lot of memory leaks when an error is encountered (caused by
1819 procinfo and pstringcontainers). There are still plenty left though :)
1821 Revision 1.179 2000/01/11 09:52:07 peter
1822 * fixed placing of .sl directories
1823 * use -b again for base-file selection
1824 * fixed group writing for linux with smartlinking
1826 Revision 1.178 2000/01/07 01:14:29 peter
1827 * updated copyright to 2000
1829 Revision 1.177 1999/12/20 22:29:26 pierre
1830 * relocation with debug info in rva (only with internal compiler)
1832 Revision 1.176 1999/12/10 10:02:53 peter
1833 * only check relocsection for win32
1835 Revision 1.175 1999/11/30 10:40:44 peter
1838 Revision 1.174 1999/11/29 16:24:52 pierre
1839 * bug in previous commit corrected
1841 Revision 1.173 1999/11/29 15:18:27 pierre
1842 + allow exports in win32 executables
1844 Revision 1.172 1999/11/24 11:41:05 pierre
1845 * defaultsymtablestack is now restored after parser.compile
1847 Revision 1.171 1999/11/22 22:21:46 pierre
1848 * Compute correct Exe Filenam
1850 Revision 1.170 1999/11/22 00:23:09 pierre
1851 * also complain about unused functions in program
1853 Revision 1.169 1999/11/20 01:19:10 pierre
1854 * DLL index used for win32 target with DEF file
1855 + DLL initialization/finalization support
1857 Revision 1.168 1999/11/18 23:35:40 pierre
1858 * avoid double warnings
1860 Revision 1.167 1999/11/18 15:34:47 pierre
1861 * Notes/Hints for local syms changed to
1862 Set_varstate function
1864 Revision 1.166 1999/11/17 17:05:02 pierre
1865 * Notes/hints changes
1867 Revision 1.165 1999/11/15 15:03:47 pierre
1868 * Pavel's changes for reloc section in executable
1869 + warning that -g needs -WN under win32