* also recompile a unit if class/object definitions in indirectly used

units have changed, because these can influence the code of the
    current unit in case method signatures changed (mantis #13840)
    + manual test
  * fixed some recompilation crashes related to WPO info
  * clarified the unit_u_add_depend_to message

git-svn-id: trunk@14503 -
This commit is contained in:
Jonas Maebe 2009-12-30 14:03:31 +00:00
parent 58c7c2f636
commit 1743c6f1a8
16 changed files with 477 additions and 206 deletions

5
.gitattributes vendored
View File

@ -10088,6 +10088,11 @@ tests/webtbs/tw1376.pp svneol=native#text/plain
tests/webtbs/tw13763.pp svneol=native#text/plain
tests/webtbs/tw13813.pp svneol=native#text/plain
tests/webtbs/tw13820.pp svneol=native#text/plain
tests/webtbs/tw13840/doit.sh svneol=LF#text/plain eol=lf
tests/webtbs/tw13840/tw13840a.pp svneol=native#text/plain
tests/webtbs/tw13840/tw13840b.pp svneol=native#text/plain
tests/webtbs/tw13840/tw13840c.pp svneol=native#text/plain
tests/webtbs/tw13840/tw13840d.pp svneol=native#text/plain
tests/webtbs/tw13872.pp svneol=native#text/plain
tests/webtbs/tw13890.pp svneol=native#text/plain
tests/webtbs/tw13948.pp svneol=native#text/plain

View File

@ -115,7 +115,8 @@ interface
mainfilepos : tfileposinfo;
recompile_reason : trecompile_reason; { the reason why the unit should be recompiled }
crc,
interface_crc : cardinal;
interface_crc,
indirect_crc : cardinal;
flags : cardinal; { the PPU flags }
islibrary : boolean; { if it is a library (win32 dll) }
IsPackage : boolean;
@ -183,7 +184,8 @@ interface
tused_unit = class(tlinkedlistitem)
checksum,
interface_checksum : cardinal;
interface_checksum,
indirect_checksum: cardinal;
in_uses,
in_interface : boolean;
u : tmodule;
@ -420,11 +422,13 @@ implementation
begin
checksum:=u.crc;
interface_checksum:=u.interface_crc;
indirect_checksum:=u.indirect_crc;
end
else
begin
checksum:=0;
interface_checksum:=0;
indirect_checksum:=0;
end;
end;
@ -480,6 +484,7 @@ implementation
FImportLibraryList:=TFPHashObjectList.Create(true);
crc:=0;
interface_crc:=0;
indirect_crc:=0;
flags:=0;
scanner:=nil;
unitmap:=nil;
@ -728,6 +733,7 @@ implementation
is_reset:=false;
crc:=0;
interface_crc:=0;
indirect_crc:=0;
flags:=0;
mainfilepos.line:=0;
mainfilepos.column:=0;

View File

@ -251,11 +251,13 @@ uses
flags:=ppufile.header.flags;
crc:=ppufile.header.checksum;
interface_crc:=ppufile.header.interface_checksum;
indirect_crc:=ppufile.header.indirect_checksum;
{ Show Debug info }
Message1(unit_u_ppu_time,filetimestring(ppufiletime));
Message1(unit_u_ppu_flags,tostr(flags));
Message1(unit_u_ppu_crc,hexstr(ppufile.header.checksum,8));
Message1(unit_u_ppu_crc,hexstr(ppufile.header.interface_checksum,8)+' (intfc)');
Message1(unit_u_ppu_crc,hexstr(ppufile.header.indirect_checksum,8)+' (indc)');
Comment(V_used,'Number of definitions: '+tostr(ppufile.header.deflistsize));
Comment(V_used,'Number of symbols: '+tostr(ppufile.header.symlistsize));
do_compile:=false;
@ -515,7 +517,11 @@ uses
ppufile.do_crc:=false;
ppufile.putlongint(longint(hp.checksum));
ppufile.putlongint(longint(hp.interface_checksum));
ppufile.putlongint(longint(hp.indirect_checksum));
ppufile.do_crc:=oldcrc;
{ combine all indirect checksums from units used by this unit }
if intf then
ppufile.indirect_crc:=ppufile.indirect_crc xor hp.indirect_checksum;
end;
hp:=tused_unit(hp.next);
end;
@ -810,6 +816,7 @@ uses
hs : string;
pu : tused_unit;
hp : tppumodule;
indchecksum,
intfchecksum,
checksum : cardinal;
begin
@ -818,12 +825,14 @@ uses
hs:=ppufile.getstring;
checksum:=cardinal(ppufile.getlongint);
intfchecksum:=cardinal(ppufile.getlongint);
indchecksum:=cardinal(ppufile.getlongint);
{ set the state of this unit before registering, this is
needed for a correct circular dependency check }
hp:=registerunit(self,hs,'');
pu:=addusedunit(hp,false,nil);
pu.checksum:=checksum;
pu.interface_checksum:=intfchecksum;
pu.indirect_checksum:=indchecksum;
end;
in_interface:=false;
end;
@ -1152,6 +1161,7 @@ uses
ppufile.header.size:=ppufile.size;
ppufile.header.checksum:=ppufile.crc;
ppufile.header.interface_checksum:=ppufile.interface_crc;
ppufile.header.indirect_checksum:=ppufile.indirect_crc;
ppufile.header.compiler:=wordversion;
ppufile.header.cpu:=word(target_cpu);
ppufile.header.target:=word(target_info.system);
@ -1163,6 +1173,7 @@ uses
{ save crc in current module also }
crc:=ppufile.crc;
interface_crc:=ppufile.interface_crc;
indirect_crc:=ppufile.indirect_crc;
{$ifdef Test_Double_checksum_write}
close(CRCFile);
@ -1221,6 +1232,7 @@ uses
{ save crc }
crc:=ppufile.crc;
interface_crc:=ppufile.interface_crc;
indirect_crc:=ppufile.indirect_crc;
{ end of implementation, to generate a correct ppufile
for ppudump when using INTFPPU define }
@ -1244,6 +1256,7 @@ uses
ppufile.header.size:=ppufile.size;
ppufile.header.checksum:=ppufile.crc;
ppufile.header.interface_checksum:=ppufile.interface_crc;
ppufile.header.indirect_checksum:=ppufile.indirect_crc;
ppufile.header.compiler:=wordversion;
ppufile.header.cpu:=word(target_cpu);
ppufile.header.target:=word(target_info.system);
@ -1280,12 +1293,21 @@ uses
crc. And when not compiled with -Ur then check the complete
crc }
if (pu.u.interface_crc<>pu.interface_checksum) or
(pu.u.indirect_crc<>pu.indirect_checksum) or
(
((ppufile.header.flags and uf_release)=0) and
(pu.u.crc<>pu.checksum)
) then
begin
Message2(unit_u_recompile_crc_change,realmodulename^,pu.u.realmodulename^,@queuecomment);
{$ifdef DEBUG_UNIT_CRC_CHANGES}
if (pu.u.interface_crc<>pu.interface_checksum) then
writeln(' intfcrc change: ',hexstr(pu.u.interface_crc,8),' <> ',hexstr(pu.interface_checksum,8))
else if (pu.u.indirect_crc<>pu.indirect_checksum) then
writeln(' indcrc change: ',hexstr(pu.u.indirect_crc,8),' <> ',hexstr(pu.indirect_checksum,8))
else
writeln(' implcrc change: ',hexstr(pu.u.crc,8),' <> ',hexstr(pu.checksum,8));
{$endif DEBUG_UNIT_CRC_CHANGES}
recompile_reason:=rr_crcchanged;
do_compile:=true;
exit;
@ -1330,9 +1352,16 @@ uses
{ add this unit to the dependencies }
pu.u.adddependency(self);
{ need to recompile the current unit ? }
if (pu.u.interface_crc<>pu.interface_checksum) then
if (pu.u.interface_crc<>pu.interface_checksum) or
(pu.u.indirect_crc<>pu.indirect_checksum) then
begin
Message2(unit_u_recompile_crc_change,realmodulename^,pu.u.realmodulename^+' {impl}',@queuecomment);
{$ifdef DEBUG_UNIT_CRC_CHANGES}
if (pu.u.interface_crc<>pu.interface_checksum) then
writeln(' intfcrc change (2): ',hexstr(pu.u.interface_crc,8),' <> ',hexstr(pu.interface_checksum,8))
else if (pu.u.indirect_crc<>pu.indirect_checksum) then
writeln(' indcrc change (2): ',hexstr(pu.u.indirect_crc,8),' <> ',hexstr(pu.indirect_checksum,8));
{$endif DEBUG_UNIT_CRC_CHANGES}
recompile_reason:=rr_crcchanged;
do_compile:=true;
exit;
@ -1372,11 +1401,20 @@ uses
crc. And when not compiled with -Ur then check the complete
crc }
if (pu.u.interface_crc<>pu.interface_checksum) or
(pu.u.indirect_crc<>pu.indirect_checksum) or
(
(pu.in_interface) and
(pu.u.crc<>pu.checksum)
) then
begin
{$ifdef DEBUG_UNIT_CRC_CHANGES}
if (pu.u.interface_crc<>pu.interface_checksum) then
writeln(' intfcrc change (3): ',hexstr(pu.u.interface_crc,8),' <> ',hexstr(pu.interface_checksum,8))
else if (pu.u.indirect_crc<>pu.indirect_checksum) then
writeln(' indcrc change (3): ',hexstr(pu.u.indirect_crc,8),' <> ',hexstr(pu.indirect_checksum,8))
else
writeln(' implcrc change (3): ',hexstr(pu.u.crc,8),' <> ',hexstr(pu.checksum,8));
{$endif DEBUG_UNIT_CRC_CHANGES}
result:=true;
exit;
end;
@ -1390,7 +1428,8 @@ uses
ImplIntf : array[boolean] of string[15]=('implementation','interface');
var
do_load,
second_time : boolean;
second_time,
reresolvedependent: boolean;
old_current_module : tmodule;
begin
old_current_module:=current_module;
@ -1410,6 +1449,7 @@ uses
{ reset }
do_load:=true;
second_time:=false;
reresolvedependent:=false;
set_current_module(self);
{ A force reload }
@ -1434,8 +1474,7 @@ uses
tstoredsymtable(localsymtable).deref;
tstoredsymtable(localsymtable).derefimpl;
end;
tunitwpoinfo(wpoinfo).deref;
tunitwpoinfo(wpoinfo).derefimpl;
reresolvedependent:=true;
end
else
Message1(unit_u_skipping_reresolving_unit,modulename^);
@ -1556,7 +1595,29 @@ uses
assigned(tppumodule(old_current_module).ppufile) then
tppumodule(old_current_module).ppufile.tempopen;
{$endif SHORT_ON_FILE_HANDLES}
end;
end
else if reresolvedependent then
begin
{ only reresolve the wpoinfo now that this unit (and hence all of
its dependent units) have been reloaded/recompiled, because the
wpo info can depend those units' interface defs. }
if assigned(wpoinfo) then
begin
tunitwpoinfo(wpoinfo).deref;
tunitwpoinfo(wpoinfo).derefimpl;
end;
{ We have to flag the units that depend on this unit even
though it didn't change, because they might also
indirectly depend on the unit that did change (e.g.,
in case rgobj, rgx86 and rgcpu have been compiled
already, and then rgobj is recompiled for some reason
-> rgx86 is re-reresolved, but the vmtentries of trgcpu
must also be re-resolved, because they will also contain
pointers to procdefs in the old trgobj (in case of a
recompile, all old defs are freed) }
flagdependent(old_current_module);
reload_flagged_units;
end;
{ we are back, restore current_module }
set_current_module(old_current_module);

View File

@ -2370,7 +2370,7 @@ link_w_32bit_absolute_reloc=09201_W_Object file "$1" contains 32-bit absolute re
#
# Unit loading
#
# 10061 is the last used one
# 10062 is the last used one
#
# BeginOfTeX
% \section{Unit loading messages.}
@ -2521,7 +2521,7 @@ unit_u_implementation_crc_changed=10046_U_Implementation CRC changed for unit $1
unit_u_finished_compiling=10047_U_Finished compiling unit $1
% When you use the \var{-vu} flag, the compiler warns that it
% has finished compiling the unit.
unit_u_add_depend_to=10048_U_Add dependency of $1 to $2
unit_u_add_depend_to=10048_U_Adding dependency: $1 depends on $2
% When you use the \var{-vu} flag, the compiler warns that it
% has added a dependency between the two units.
unit_u_no_reload_is_caller=10049_U_No reload, is caller: $1
@ -2567,6 +2567,11 @@ unit_e_different_wpo_file=10061_E_Unit $1 was compiled using a different whole p
% When a unit has been compiled using a particular whole program optimization (wpo) feedback file (\var{-FW<x>} \var{-OW<x>}),
% this compiled version of the unit is specialised for that particular compilation scenario and cannot be used in
% any other context. It has to be recompiled before you can use it in another program or with another wpo feedback input file.
unit_u_indirect_crc_changed=10062_U_Indirect interface (objects/classes) CRC changed for unit $1
% When you use the \var{-vu} flag, the compiler warns that the
% indirect CRC calculated for the unit (this is the CRC of all classes/objects/interfaces/$\ldots$
% in the interfaces of units directly or indirectly used by this unit in the interface) has been changed after the
% implementation has been parsed.
% \end{description}
# EndOfTeX

View File

@ -768,6 +768,7 @@ const
unit_u_skipping_reresolving_unit=10059;
unit_u_unload_resunit=10060;
unit_e_different_wpo_file=10061;
unit_u_indirect_crc_changed=10062;
option_usage=11000;
option_only_one_source_support=11001;
option_def_only_for_os2=11002;
@ -836,9 +837,9 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 54952;
MsgTxtSize = 55030;
MsgIdxMax : array[1..20] of longint=(
24,87,282,95,71,51,110,22,202,62,
24,87,282,95,71,51,110,22,202,63,
49,20,1,1,1,1,1,1,1,1
);

View File

@ -1,7 +1,7 @@
{$ifdef Delphi}
const msgtxt : array[0..000228] of string[240]=(
const msgtxt : array[0..000229] of string[240]=(
{$else Delphi}
const msgtxt : array[0..000228,1..240] of char=(
const msgtxt : array[0..000229,1..240] of char=(
{$endif Delphi}
'01000_T_Compiler: $1'#000+
'01001_D_Compiler OS: $1'#000+
@ -865,125 +865,126 @@ const msgtxt : array[0..000228,1..240] of char=(
'10045_','U_Interface CRC changed for unit $1'#000+
'10046_U_Implementation CRC changed for unit $1'#000+
'10047_U_Finished compiling unit $1'#000+
'10048_U_Add dependency of $1 to $2'#000+
'10048_U_Adding dependency: $1 depends on $2'#000+
'10049_U_No reload, is caller: $1'#000+
'10050_U_No reload, already in second compile: $1'#000+
'10051','_U_Flag for reload: $1'#000+
'10050_U_No reload, already in second compile:',' $1'#000+
'10051_U_Flag for reload: $1'#000+
'10052_U_Forced reloading'#000+
'10053_U_Previous state of $1: $2'#000+
'10054_U_Already compiling $1, setting second compile'#000+
'10055_U_Loading unit $1'#000+
'10056_U_Finished loading unit $1'#000+
'10057_U_Registering new unit $1'#000+
'10058_U_Re-resolv','ing unit $1'#000+
'10058_U_','Re-resolving unit $1'#000+
'10059_U_Skipping re-resolving unit $1, still loading used units'#000+
'10060_U_Unloading resource unit $1 (not needed)'#000+
'10061_E_Unit $1 was compiled using a different whole program optimizat'+
'ion feedback input ($2, $3); recompile it with','out wpo or use the sam'+
'ion feedback input ($2, $3); recompil','e it without wpo or use the sam'+
'e wpo feedback input file for this compilation invocation'#000+
'10062_U_Indirect interface (objects/classes) CRC changed for unit $1'#000+
'11000_O_$1 [options] <inputfile> [options]'#000+
'11001_W_Only one source file supported, changing source file to compil'+
'e from "$1" into "$2"'#000+
'11002_W_DEF file can be c','reated only for OS/2'#000+
'11001_W_Only one source file supported,',' changing source file to comp'+
'ile from "$1" into "$2"'#000+
'11002_W_DEF file can be created only for OS/2'#000+
'11003_E_nested response files are not supported'#000+
'11004_F_No source file name in command line'#000+
'11005_N_No option inside $1 config file'#000+
'11006_E_Illegal parameter: $1'#000+
'11006_E_I','llegal parameter: $1'#000+
'11007_H_-? writes help pages'#000+
'11008_F_Too many config file','s nested'#000+
'11008_F_Too many config files nested'#000+
'11009_F_Unable to open file $1'#000+
'11010_D_Reading further options from $1'#000+
'11011_W_Target is already set to: $1'#000+
'11012_W_Shared libs not supported on DOS platform, reverting to static'+
#000+
'11013_F_In options file $1 at line $2 too many \var{','\#IF(N)DEFs} enc'+
'ountered'#000+
'11012_W_Shared libs not supported on DOS plat','form, reverting to stat'+
'ic'#000+
'11013_F_In options file $1 at line $2 too many \var{\#IF(N)DEFs} encou'+
'ntered'#000+
'11014_F_In options file $1 at line $2 unexpected \var{\#ENDIFs} encoun'+
'tered'#000+
'11015_F_Open conditional at the end of the options file'#000+
'11016_W_Debug information generation is not supported by this executab'+
'le'#000+
'11017_H_Tr','y recompiling with -dGDB'#000+
'11016','_W_Debug information generation is not supported by this execut'+
'able'#000+
'11017_H_Try recompiling with -dGDB'#000+
'11018_W_You are using the obsolete switch $1'#000+
'11019_W_You are using the obsolete switch $1, please use $2'#000+
'11020_N_Switching assembler to default source writing assembler'#000+
'11021_W_Assembler output selected "$1" is not ','compatible with "$2"'#000+
'11020_N_Switching assembler to d','efault source writing assembler'#000+
'11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
'11022_W_"$1" assembler use forced'#000+
'11026_T_Reading options from file $1'#000+
'11027_T_Reading options from environment $1'#000+
'11028_D_Handling option "$1"'#000+
'11028_D_Handling option "$','1"'#000+
'11029_O_*** press enter ***'#000+
'11030_H_Start of reading config file $1'#000+
'11031_H','_End of reading config file $1'#000+
'11031_H_End of reading config file $1'#000+
'11032_D_interpreting option "$1"'#000+
'11036_D_interpreting firstpass option "$1"'#000+
'11033_D_interpreting file option "$1"'#000+
'11034_D_Reading config file "$1"'#000+
'11034_D_Reading c','onfig file "$1"'#000+
'11035_D_found source file name "$1"'#000+
'11039_E_Unknown code page'#000,
'11039_E_Unknown code page'#000+
'11040_F_Config file $1 is a directory'#000+
'11041_W_Assembler output selected "$1" cannot generate debug info, deb'+
'ugging disabled'#000+
'11042_W_Use of ppc386.cfg is deprecated, please use fpc.cfg instead'#000+
'11043_F_In options file $1 at line $2 \var{\#ELS','E} directive without'+
' \var{\#IF(N)DEF} found'#000+
'11042_W_Use of ppc386.cfg is deprecate','d, please use fpc.cfg instead'#000+
'11043_F_In options file $1 at line $2 \var{\#ELSE} directive without \'+
'var{\#IF(N)DEF} found'#000+
'11044_F_Option "$1" is not, or not yet, supported on the current targe'+
't platform'#000+
'11045_F_The feature "$1" is not, or not yet, supported on the selected'+
' target platform'#000+
'11046_N_DWARF debug informat','ion cannot be used with smart linking on'+
' this target, switching to static linking'#000+
'11045_F_The feature "$1" is not, or n','ot yet, supported on the select'+
'ed target platform'#000+
'11046_N_DWARF debug information cannot be used with smart linking on t'+
'his target, switching to static linking'#000+
'11047_W_Option "$1" is ignored for the current target platform.'#000+
'11048_W_Disabling external debug information because it is unsupported'+
' for the selected target','/debug format combination.'#000+
'11048_W_Disablin','g external debug information because it is unsupport'+
'ed for the selected target/debug format combination.'#000+
'12000_F_Cannot open whole program optimization feedback file "$1"'#000+
'12001_D_Processing whole program optimization information in wpo feedb'+
'ack file "$1"'#000+
'12002_D_Finished processing the whole program optimization info','rmati'+
'on in wpo feedback file "$1"'#000+
'12001_D_Processing whole program optimization information in wpo feed',
'back file "$1"'#000+
'12002_D_Finished processing the whole program optimization information'+
' in wpo feedback file "$1"'#000+
'12003_E_Expected section header, but got "$2" at line $1 of wpo feedba'+
'ck file'#000+
'12004_W_No handler registered for whole program optimization section "'+
'$2" at line $1 of wpo feedback file, ignoring'#000+
'12005_D_Foun','d whole program optimization section "$1" with informati'+
'on about "$2"'#000+
'12004_W_No handler registered for whole program op','timization section'+
' "$2" at line $1 of wpo feedback file, ignoring'#000+
'12005_D_Found whole program optimization section "$1" with information'+
' about "$2"'#000+
'12006_F_The selected whole program optimizations require a previously '+
'generated feedback file (use -Fw to specify)'#000+
'12007_E_No collected information necessary to perform "','$1" whole pro'+
'gram optimization found'#000+
'generated feedback fil','e (use -Fw to specify)'#000+
'12007_E_No collected information necessary to perform "$1" whole progr'+
'am optimization found'#000+
'12008_F_Specify a whole program optimization feedback file to store th'+
'e generated info in (using -FW)'#000+
'12009_E_Not generating any whole program optimization information, yet'+
' a feedback file was specified ','(using -FW)'#000+
'12009_E_Not generating ','any whole program optimization information, y'+
'et a feedback file was specified (using -FW)'#000+
'12010_E_Not performing any whole program optimizations, yet an input f'+
'eedback file was specified (using -Fw)'#000+
'12011_D_Skipping whole program optimization section "$1", because not '+
'needed by the requested optimizations'#000+
'12012_W_Ove','rriding previously read information for "$1" from feedbac'+
'k input file using information in section "$2"'#000+
'12013_E_Cannot extract symbol liveness information from program when s'+
'tripping symbols, use -Xs-'#000+
'12014_E_Cannot extract symbol liveness ','information from program when'+
' when not linking'#000+
'12011_D_Skipping whole program optimizati','on section "$1", because no'+
't needed by the requested optimizations'#000+
'12012_W_Overriding previously read information for "$1" from feedback '+
'input file using information in section "$2"'#000+
'12013_E_Cannot extract symbol liveness information from pr','ogram when'+
' stripping symbols, use -Xs-'#000+
'12014_E_Cannot extract symbol liveness information from program when w'+
'hen not linking'#000+
'12015_F_Cannot find "$1" or "$2" to extract symbol liveness informatio'+
'n from linked program'#000+
'12016_E_Error during reading symbol liveness information produced by "'+
'$1"'#000+
'12017_F_Error executing "$1','" (exitcode: $2) to extract symbol inform'+
'ation from linked program'#000+
'12016_E_Error during re','ading symbol liveness information produced by'+
' "$1"'#000+
'12017_F_Error executing "$1" (exitcode: $2) to extract symbol informat'+
'ion from linked program'#000+
'12018_E_Collection of symbol liveness information can only help when u'+
'sing smart linking, use -CX -XX'#000+
'sing smart linking, use -','CX -XX'#000+
'12019_E_Cannot create specified whole program optimisation feedback fi'+
'l','e "$1"'#000+
'le "$1"'#000+
'11023_Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] for $FPC'+
'CPU'#010+
'Copyright (c) 1993-2009 by Florian Klaempfl'#000+
'11024_Free Pascal Compiler version $FPCVERSION'#010+
'11024_Free Pascal Compiler version $F','PCVERSION'#010+
#010+
'Compiler Date : $FPCDATE'#010+
'Compiler CPU Target: $FPCCPU'#010+
#010+
'Support','ed targets:'#010+
'Supported targets:'#010+
' $OSTARGETS'#010+
#010+
'Supported CPU instruction sets:'#010+
@ -993,12 +994,12 @@ const msgtxt : array[0..000228,1..240] of char=(
' $FPUINSTRUCTIONSETS'#010+
#010+
'Supported ABI targets:'#010+
' $ABITARGETS'#010+
' $ABI','TARGETS'#010+
#010+
'Supported Optimizations:'#010+
' $OPTIMIZATIONS'#010+
#010+
'Supported Whole Program Op','timizations:'#010+
'Supported Whole Program Optimizations:'#010+
' All'#010+
' $WPOPTIMIZATIONS'#010+
#010+
@ -1006,293 +1007,291 @@ const msgtxt : array[0..000228,1..240] of char=(
' $CONTROLLERTYPES'#010+
#010+
'This program comes under the GNU General Public Licence'#010+
'For more information read COPYING.FPC'#010+
'For more infor','mation read COPYING.FPC'#010+
#010+
'Report bugs, suggestions, etc. to:'#010+
' h','ttp://bugs.freepascal.org'#010+
' http://bugs.freepascal.org'#010+
'or'#010+
' bugs@freepascal.org'#000+
'11025_**0*_Put + after a boolean switch option to enable it, - to disa'+
'ble it'#010+
'**1a_The compiler doesn'#039't delete the generated assembler file'#010+
'**2al_List sourcecode lines in asse','mbler file'#010+
'**1a_The compiler d','oesn'#039't delete the generated assembler file'#010+
'**2al_List sourcecode lines in assembler file'#010+
'**2an_List node info in assembler file'#010+
'*L2ap_Use pipes instead of creating temporary assembler files'#010+
'**2ar_List register allocation/release info in assembler file'#010+
'**2ar_List register allocation/release info in ass','embler file'#010+
'**2at_List temp allocation/release info in assembler file'#010+
'**1A<x>_','Output format:'#010+
'**1A<x>_Output format:'#010+
'**2Adefault_Use default assembler'#010+
'3*2Aas_Assemble using GNU AS'#010+
'3*2Anasmcoff_COFF (Go32v2) file using Nasm'#010+
'3*2Anasmelf_ELF32 (Linux) file using Nasm'#010+
'3*2Anasmelf_ELF32 (Linux) file using Nasm',#010+
'3*2Anasmwin32_Win32 object file using Nasm'#010+
'3*2Anasmwdosx_Win32/WDOSX object f','ile using Nasm'#010+
'3*2Anasmwdosx_Win32/WDOSX object file using Nasm'#010+
'3*2Awasm_Obj file using Wasm (Watcom)'#010+
'3*2Anasmobj_Obj file using Nasm'#010+
'3*2Amasm_Obj file using Masm (Microsoft)'#010+
'3*2Atasm_Obj file using Tasm (Borland)'#010+
'3*2Atasm_Obj file using Tasm (Borlan','d)'#010+
'3*2Aelf_ELF (Linux) using internal writer'#010+
'3*2Acoff_COFF (Go32v2) using inte','rnal writer'#010+
'3*2Acoff_COFF (Go32v2) using internal writer'#010+
'3*2Apecoff_PE-COFF (Win32) using internal writer'#010+
'4*2Aas_Assemble using GNU AS'#010+
'6*2Aas_Unix o-file using GNU AS'#010+
'6*2Agas_GNU Motorola assembler'#010+
'6*2Amit_MIT Syntax (old GAS)'#010+
'6*2Amit_M','IT Syntax (old GAS)'#010+
'6*2Amot_Standard Motorola assembler'#010+
'A*2Aas_Assemble using ','GNU AS'#010+
'A*2Aas_Assemble using GNU AS'#010+
'P*2Aas_Assemble using GNU AS'#010+
'S*2Aas_Assemble using GNU AS'#010+
'**1b_Generate browser info'#010+
'**2bl_Generate local symbol info'#010+
'**1B_Build all modules'#010+
'**1C<x>_Code generation options:'#010+
'**1C<x>_Code g','eneration options:'#010+
'**2Ca<x>_Select ABI, see fpc -i for possible values'#010+
'**2Cb_G','enerate big-endian code'#010+
'**2Cb_Generate big-endian code'#010+
'**2Cc<x>_Set default calling convention to <x>'#010+
'**2CD_Create also dynamic library (not supported)'#010+
'**2Ce_Compilation with emulated floating point opcodes'#010+
'**2Cf<x>_Select fpu instruction set to use, see fpc -i for possi','ble '+
'values'#010+
'**2Ce_Compilation with emulated floating ','point opcodes'#010+
'**2Cf<x>_Select fpu instruction set to use, see fpc -i for possible va'+
'lues'#010+
'**2CF<x>_Minimal floating point constant precision (default, 32, 64)'#010+
'**2Cg_Generate PIC code'#010+
'**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
'**2Ci_IO-checking'#010+
'**2Ci_','IO-checking'#010+
'**2Cn_Omit linking stage'#010+
'**2Co_Check overflow of integer operation','s'#010+
'**2Co_Check overflow of integer operations'#010+
'**2CO_Check for possible overflow of integer operations'#010+
'**2Cp<x>_Select instruction set, see fpc -i for possible values'#010+
'**2CP<x>=<y>_ packing settings'#010+
'**3CPPACKSET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, 4 '+
'and 8'#010+
'**2Cr_Range',' checking'#010+
'**3CPPACK','SET=<y>_ <y> set allocation: 0, 1 or DEFAULT or NORMAL, 2, '+
'4 and 8'#010+
'**2Cr_Range checking'#010+
'**2CR_Verify object method call validity'#010+
'**2Cs<n>_Set stack checking size to <n>'#010+
'**2Ct_Stack checking (for testing only, see manual)'#010+
'**2CX_Create also smartlinked library'#010+
'**2CX_Create also s','martlinked library'#010+
'**1d<x>_Defines the symbol <x>'#010+
'**1D_Generate a DEF file'#010+
'**2','Dd<x>_Set description to <x>'#010+
'**2Dd<x>_Set description to <x>'#010+
'**2Dv<x>_Set DLL version to <x>'#010+
'*O2Dw_PM application'#010+
'**1e<x>_Set path to executable'#010+
'**1E_Same as -Cn'#010+
'**1fPIC_Same as -Cg'#010+
'**1F<x>_Set file names and paths:'#010+
'**2Fa<x>[,y]_(for a program) load units <x> and [y] befo','re uses is p'+
'arsed'#010+
'**1F<x>_Set ','file names and paths:'#010+
'**2Fa<x>[,y]_(for a program) load units <x> and [y] before uses is par'+
'sed'#010+
'**2Fc<x>_Set input codepage to <x>'#010+
'**2FC<x>_Set RC compiler binary name to <x>'#010+
'**2Fd_Disable the compiler'#039's internal directory cache'#010+
'**2FD<x>_Set the directory where to search for compiler utilities'#010+
'**2Fe<x>_Redirect error',' output to <x>'#010+
'**2FD<x>_Se','t the directory where to search for compiler utilities'#010+
'**2Fe<x>_Redirect error output to <x>'#010+
'**2Ff<x>_Add <x> to framework path (Darwin only)'#010+
'**2FE<x>_Set exe/unit output path to <x>'#010+
'**2Fi<x>_Add <x> to include path'#010+
'**2Fl<x>_Add <x> to library path'#010+
'**2Fl<x>_Add <x> to libr','ary path'#010+
'**2FL<x>_Use <x> as dynamic linker'#010+
'**2Fm<x>_Load unicode conversion t','able from <x>.txt in the compiler '+
'dir'#010+
'**2Fm<x>_Load unicode conversion table from <x>.txt in the compiler di'+
'r'#010+
'**2Fo<x>_Add <x> to object path'#010+
'**2Fr<x>_Load error message file <x>'#010+
'**2FR<x>_Set resource (.res) linker to <x>'#010+
'**2Fu<x>_Add <x> to unit path'#010+
'**2Fu<x>_Add',' <x> to unit path'#010+
'**2FU<x>_Set unit output path to <x>, overrides -FE'#010+
'**2FW<x>','_Store generated whole-program optimization feedback in <x>'#010+
'**2FW<x>_Store generated whole-program optimization feedback in <x>'#010+
'**2Fw<x>_Load previously stored whole-program optimization feedback fr'+
'om <x>'#010+
'*g1g_Generate debug information (default format for target)'#010+
'*g1g_Generate debug infor','mation (default format for target)'#010+
'*g2gc_Generate checks for pointers'#010+
'*g2gh_Us','e heaptrace unit (for memory leak/corruption debugging)'#010+
'*g2gh_Use heaptrace unit (for memory leak/corruption debugging)'#010+
'*g2gl_Use line info unit (show more info with backtraces)'#010+
'*g2go<x>_Set debug information options'#010+
'*g3godwarfsets_ Enable DWARF '#039'set'#039' type debug information (bre'+
'aks gdb < 6.5)'#010+
'*g3gostabs','absincludes_ Store absolute/full include file paths in Sta'+
'bs'#010+
'*g3godwar','fsets_ Enable DWARF '#039'set'#039' type debug information (b'+
'reaks gdb < 6.5)'#010+
'*g3gostabsabsincludes_ Store absolute/full include file paths in Stabs'+
#010+
'*g3godwarfmethodclassprefix_ Prefix method names in DWARF with class n'+
'ame'#010+
'*g2gp_Preserve case in stabs symbol names'#010+
'*g2gp_Preserve case in stab','s symbol names'#010+
'*g2gs_Generate Stabs debug information'#010+
'*g2gt_Trash local variab','les (to detect uninitialized uses)'#010+
'*g2gt_Trash local variables (to detect uninitialized uses)'#010+
'*g2gv_Generates programs traceable with Valgrind'#010+
'*g2gw_Generate DWARFv2 debug information (same as -gw2)'#010+
'*g2gw2_Generate DWARFv2 debug information'#010+
'*g2gw2_Generate DWARFv','2 debug information'#010+
'*g2gw3_Generate DWARFv3 debug information'#010+
'**1i_Information',#010+
'**1i_Information'#010+
'**2iD_Return compiler date'#010+
'**2iV_Return short compiler version'#010+
'**2iW_Return full compiler version'#010+
'**2iSO_Return compiler OS'#010+
'**2iSP_Return compiler host processor'#010+
'**2iSP_Return compiler host processor',#010+
'**2iTO_Return target OS'#010+
'**2iTP_Return target processor'#010+
'**1I<x>_Add <x> to inc','lude path'#010+
'**1I<x>_Add <x> to include path'#010+
'**1k<x>_Pass <x> to the linker'#010+
'**1l_Write logo'#010+
'**1M<x>_Set language mode to <x>'#010+
'**2Mfpc_Free Pascal dialect (default)'#010+
'**2Mobjfpc_FPC mode with Object Pascal support'#010+
'**2Mobjfpc_FPC mode with Object Pa','scal support'#010+
'**2Mdelphi_Delphi 7 compatibility mode'#010+
'**2Mtp_TP/BP 7.0 compatibi','lity mode'#010+
'**2Mtp_TP/BP 7.0 compatibility mode'#010+
'**2Mmacpas_Macintosh Pascal dialects compatibility mode'#010+
'**1n_Do not read the default config files'#010+
'**1N<x>_Node tree optimizations'#010+
'**2Nu_Unroll loops'#010+
'**1o<x>_Change the name of the executable produced to <x>'#010+
'**1O<x>_Optimizations:'#010,
'**1','o<x>_Change the name of the executable produced to <x>'#010+
'**1O<x>_Optimizations:'#010+
'**2O-_Disable optimizations'#010+
'**2O1_Level 1 optimizations (quick and debugger friendly)'#010+
'**2O2_Level 2 optimizations (-O1 + quick optimizations)'#010+
'**2O3_Level 3 optimizations (-O2 + slow optimizations)'#010+
'**2O3_Level 3 optimi','zations (-O2 + slow optimizations)'#010+
'**2Oa<x>=<y>_Set alignment'#010+
'**2Oo[NO]<x>_Ena','ble or disable optimizations, see fpc -i for possibl'+
'e values'#010+
'**2Oo[NO]<x>_Enable or disable optimizations, see fpc -i for possible '+
'values'#010+
'**2Op<x>_Set target cpu for optimizing, see fpc -i for possible values'+
#010+
'**2OW<x>_Generate whole-program optimization feedback for optimization'+
' <x>, see fpc -i for possible values'#010+
'*','*2Ow<x>_Perform whole-program optimization <x>, see fpc -i for poss'+
'ible values'#010+
'**2OW<x>_Generate whole-progra','m optimization feedback for optimizati'+
'on <x>, see fpc -i for possible values'#010+
'**2Ow<x>_Perform whole-program optimization <x>, see fpc -i for possib'+
'le values'#010+
'**2Os_Optimize for size rather than speed'#010+
'**1pg_Generate profile code for gprof (defines FPC_PROFILE)'#010+
'**1pg_Generate profile code for gprof (de','fines FPC_PROFILE)'#010+
'**1R<x>_Assembler reading style:'#010+
'**2Rdefault_Use default as','sembler for target'#010+
'**2Rdefault_Use default assembler for target'#010+
'3*2Ratt_Read AT&T style assembler'#010+
'3*2Rintel_Read Intel style assembler'#010+
'6*2RMOT_Read motorola style assembler'#010+
'**1S<x>_Syntax options:'#010+
'**2S2_Same as -Mobjfpc'#010+
'**2S2_Same',' as -Mobjfpc'#010+
'**2Sc_Support operators like C (*=,+=,/= and -=)'#010+
'**2Sa_Turn on as','sertions'#010+
'**2Sa_Turn on assertions'#010+
'**2Sd_Same as -Mdelphi'#010+
'**2Se<x>_Error options. <x> is a combination of the following:'#010+
'**3*_<n> : Compiler halts after the <n> errors (default is 1)'#010+
'**3*_w : Compiler also halts after warnings'#010+
'**3*_n : Compiler also halts after note','s'#010+
'**3*_','w : Compiler also halts after warnings'#010+
'**3*_n : Compiler also halts after notes'#010+
'**3*_h : Compiler also halts after hints'#010+
'**2Sg_Enable LABEL and GOTO (default in -Mtp and -Mdelphi)'#010+
'**2Sh_Use ansistrings by default instead of shortstrings'#010+
'**2Si_Turn on inlining of procedures/functions declared as "inline"'#010+
'**2Sk_Load fp','cylix unit'#010+
'**2','Si_Turn on inlining of procedures/functions declared as "inline"'#010+
'**2Sk_Load fpcylix unit'#010+
'**2SI<x>_Set interface style to <x>'#010+
'**3SIcom_COM compatible interface (default)'#010+
'**3SIcorba_CORBA compatible interface'#010+
'**2Sm_Support macros like C (global)'#010+
'**2Sm_Support macros like C (glob','al)'#010+
'**2So_Same as -Mtp'#010+
'**2Ss_Constructor name must be init (destructor must be',' done)'#010+
'**2Ss_Constructor name must be init (destructor must be done)'#010+
'**2St_Allow static keyword in objects'#010+
'**2Sx_Enable exception keywords (default in Delphi/ObjFPC modes)'#010+
'**1s_Do not call assembler and linker'#010+
'**2sh_Generate script to link on host'#010+
'**2sh_Generate',' script to link on host'#010+
'**2st_Generate script to link on target'#010+
'**2sr_Skip reg','ister allocation phase (use with -alr)'#010+
'**2sr_Skip register allocation phase (use with -alr)'#010+
'**1T<x>_Target operating system:'#010+
'3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
'3*2Tfreebsd_FreeBSD'#010+
'3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
'3*2Tgo32v2_Version 2',' of DJ Delorie DOS extender'#010+
'3*2Tlinux_Linux'#010+
'3*2Tnetbsd_NetBSD'#010+
'3*2Tnetware_Nove','ll Netware Module (clib)'#010+
'3*2Tnetware_Novell Netware Module (clib)'#010+
'3*2Tnetwlibc_Novell Netware Module (libc)'#010+
'3*2Topenbsd_OpenBSD'#010+
'3*2Tos2_OS/2 / eComStation'#010+
'3*2Tsunos_SunOS/Solaris'#010+
'3*2Tsymbian_Symbian OS'#010+
'3*2Twatcom_Watcom compatible DOS extender'#010+
'3','*2Twatcom_Watcom compatible DOS extender'#010+
'3*2Twdosx_WDOSX DOS extender'#010+
'3*2Twin3','2_Windows 32 Bit'#010+
'3*2Twin32_Windows 32 Bit'#010+
'3*2Twince_Windows CE'#010+
'4*2Tlinux_Linux'#010+
'6*2Tamiga_Commodore Amiga'#010+
'6*2Tatari_Atari ST/STe/TT'#010+
'6*2Tlinux_Linux/m68k'#010+
'6*2Tmacos_Macintosh m68k (not supported)'#010+
'6*2Tmacos_Macintosh m68k (not suppo','rted)'#010+
'6*2Tpalmos_PalmOS'#010+
'A*2Tlinux_Linux'#010+
'A*2Twince_Windows CE'#010+
'P*2Tamiga_AmigaOS',' on PowerPC'#010+
'P*2Tamiga_AmigaOS on PowerPC'#010+
'P*2Tdarwin_Darwin and Mac OS X on PowerPC'#010+
'P*2Tlinux_Linux on PowerPC'#010+
'P*2Tmacos_Mac OS (classic) on PowerPC'#010+
'P*2Tmorphos_MorphOS'#010+
'S*2Tlinux_Linux'#010+
'**1u<x>_Undefines the symbol <x>'#010+
'**1u<x>','_Undefines the symbol <x>'#010+
'**1U_Unit options:'#010+
'**2Un_Do not check where the unit',' name matches the file name'#010+
'**2Un_Do not check where the unit name matches the file name'#010+
'**2Ur_Generate release unit files (never automatically recompiled)'#010+
'**2Us_Compile a system unit'#010+
'**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
'**2*_e : Show errors (default) 0 : Show noth','ing (except errors'+
')'#010+
'**1v<x>_Be verbose. <x> is a combinatio','n of the following letters:'#010+
'**2*_e : Show errors (default) 0 : Show nothing (except errors)'#010+
'**2*_w : Show warnings u : Show unit info'#010+
'**2*_n : Show notes t : Show tried/used files'#010+
'**2*_h : Show hints c : Show conditionals'#010+
'**2*_i : Show general info d : S','how debug info'#010+
'**2*_h : Show hints ',' c : Show conditionals'#010+
'**2*_i : Show general info d : Show debug info'#010+
'**2*_l : Show linenumbers r : Rhide/GCC compatibility mode'#010+
'**2*_s : Show time stamps q : Show message numbers'#010+
'**2*_a : Show everything x : Executable info (Win32 only)'#010+
'**2*_b : Write file nam','es messages p : Write tree.log with parse t'+
'ree'#010+
'**2*_a : Show e','verything x : Executable info (Win32 only'+
')'#010+
'**2*_b : Write file names messages p : Write tree.log with parse tre'+
'e'#010+
'**2*_ with full path v : Write fpcdebug.txt with'#010+
'**2*_ lots of debugging info'#010+
'**2*_ lots of',' debugging info'#010+
'**2*_m<x>,<y> : Don'#039't show messages numbered <x> and <y>'#010+
'3*1W<','x>_Target-specific options (targets)'#010+
'3*1W<x>_Target-specific options (targets)'#010+
'A*1W<x>_Target-specific options (targets)'#010+
'P*1W<x>_Target-specific options (targets)'#010+
'p*1W<x>_Target-specific options (targets)'#010+
'p*1W<x>_Target-specific options (targets)',#010+
'3*2Wb_Create a bundle instead of a library (Darwin)'#010+
'P*2Wb_Create a bundle ins','tead of a library (Darwin)'#010+
'P*2Wb_Create a bundle instead of a library (Darwin)'#010+
'p*2Wb_Create a bundle instead of a library (Darwin)'#010+
'3*2WB_Create a relocatable image (Windows)'#010+
'A*2WB_Create a relocatable image (Windows, Symbian)'#010+
'A*2WB_Create a relocatable image (Window','s, Symbian)'#010+
'3*2WC_Specify console type application (EMX, OS/2, Windows)'#010+
'A*2WC_','Specify console type application (Windows)'#010+
'A*2WC_Specify console type application (Windows)'#010+
'P*2WC_Specify console type application (Classic Mac OS)'#010+
'3*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'A*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'3*2We_Use externa','l resources (Darwin)'#010+
'A','*2WD_Use DEFFILE to export functions of DLL or EXE (Windows)'#010+
'3*2We_Use external resources (Darwin)'#010+
'P*2We_Use external resources (Darwin)'#010+
'p*2We_Use external resources (Darwin)'#010+
'3*2WF_Specify full-screen type application (EMX, OS/2)'#010+
'3*2WG_Specify graphic type application (EMX, OS/2, Windows)'#010+
'A*2WG_Specify graphic type a','pplication (Windows)'#010+
'3*2WG_Spec','ify graphic type application (EMX, OS/2, Windows)'#010+
'A*2WG_Specify graphic type application (Windows)'#010+
'P*2WG_Specify graphic type application (Classic Mac OS)'#010+
'3*2Wi_Use internal resources (Darwin)'#010+
'P*2Wi_Use internal resources (Darwin)'#010+
'p*2Wi_Use internal resources (Darwin)'#010+
'3*2WN_Do not generate relocation code, needed for',' debugging (Windows'+
')'#010+
'p*2Wi_Use',' internal resources (Darwin)'#010+
'3*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
'A*2WN_Do not generate relocation code, needed for debugging (Windows)'#010+
'3*2WR_Generate relocation code (Windows)'#010+
'A*2WR_Generate relocation code (Windows)'#010+
'A*2WR_Generate relocation code',' (Windows)'#010+
'P*2WT_Specify MPW tool type application (Classic Mac OS)'#010+
'3*2WX_Enab','le executable stack (Linux)'#010+
'3*2WX_Enable executable stack (Linux)'#010+
'A*2WX_Enable executable stack (Linux)'#010+
'p*2WX_Enable executable stack (Linux)'#010+
'P*2WX_Enable executable stack (Linux)'#010+
'**1X_Executable options:'#010+
'**1X_Executable opti','ons:'#010+
'**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Lin'+
'ux)',#010+
'ux)'#010+
'**2Xd_Do not use standard library search path (needed for cross compil'+
'e)'#010+
'**2Xe_Use external linker'#010+
'**2Xg_Create debuginfo in a separate file and add a debuglink section '+
'to executable'#010+
'**2XD_Try to link units dynamically (defines FPC_LI','NK_DYNAMIC)'#010+
'**2Xg_Create debuginfo in a separate file and add a debuglink ','sectio'+
'n to executable'#010+
'**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)'#010+
'**2Xi_Use internal linker'#010+
'**2Xm_Generate link map'#010+
'**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
's '#039'main'#039')'#010+
'**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
'**2Xr<x>_Set the linker'#039's rlink-path to <x> (neede','d for cross co'+
'mpile, see the ld manual for more information) (BeOS, Linux)'#010+
'**2XP<x>_Prepend the binutil','s names with the prefix <x>'#010+
'**2Xr<x>_Set the linker'#039's rlink-path to <x> (needed for cross comp'+
'ile, see the ld manual for more information) (BeOS, Linux)'#010+
'**2XR<x>_Prepend <x> to all linker search paths (BeOS, Darwin, FreeBSD'+
', Linux, Mac OS, Solaris)'#010+
', Linux, Mac OS, ','Solaris)'#010+
'**2Xs_Strip all symbols from executable'#010+
'**2XS_Try to link units stati','cally (default, defines FPC_LINK_STATIC'+
')'#010+
'**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
'**2Xt_Link with static libraries (-static is passed to linker)'#010+
'**2XX_Try to smartlink units (defines FPC_LINK_SMART)'#010+
'**2XX_Try to smartlink units (defines FPC_LINK','_SMART)'#010+
'**1*_'#010+
'**1?_Show this help'#010+
'**1h_Shows this help without waiting'

View File

@ -773,6 +773,7 @@ implementation
{ save crc values }
pu.checksum:=pu.u.crc;
pu.interface_checksum:=pu.u.interface_crc;
pu.indirect_checksum:=pu.u.indirect_crc;
{ connect unitsym to the module }
pu.unitsym.module:=pu.u;
{ add to symtable stack }
@ -968,7 +969,8 @@ implementation
{$ifdef EXTDEBUG}
store_crc,
{$endif EXTDEBUG}
store_interface_crc : cardinal;
store_interface_crc,
store_indirect_crc: cardinal;
s1,s2 : ^string; {Saves stack space}
force_init_final : boolean;
init_procinfo,
@ -1088,7 +1090,9 @@ implementation
needs to be added implicitly }
current_module.updatemaps;
{ create whole program optimisation information }
{ create whole program optimisation information (may already be
updated in the interface, e.g., in case of classrefdef typed
constants }
current_module.wpoinfo:=tunitwpoinfo.create;
{ ... parse the declarations }
@ -1317,6 +1321,7 @@ implementation
{ Write out the ppufile after the object file has been created }
store_interface_crc:=current_module.interface_crc;
store_indirect_crc:=current_module.indirect_crc;
{$ifdef EXTDEBUG}
store_crc:=current_module.crc;
{$endif EXTDEBUG}
@ -1324,8 +1329,12 @@ implementation
tppumodule(current_module).writeppu;
if not(cs_compilesystem in current_settings.moduleswitches) then
if store_interface_crc<>current_module.interface_crc then
Message1(unit_u_interface_crc_changed,current_module.ppufilename^);
begin
if store_interface_crc<>current_module.interface_crc then
Message1(unit_u_interface_crc_changed,current_module.ppufilename^);
if store_indirect_crc<>current_module.indirect_crc then
Message1(unit_u_indirect_crc_changed,current_module.ppufilename^);
end;
{$ifdef EXTDEBUG}
if not(cs_compilesystem in current_settings.moduleswitches) then
if (store_crc<>current_module.crc) and simplify_ppu then

View File

@ -177,7 +177,7 @@ type
interface_checksum : cardinal;
deflistsize,
symlistsize : longint;
future : array[0..0] of longint;
indirect_checksum: cardinal;
end;
tppuentry=packed record
@ -218,11 +218,18 @@ type
entrytyp : byte;
header : tppuheader;
size : integer;
{ crc for the entire unit }
crc,
interface_crc : cardinal;
{ crc for the interface definitions in this unit }
interface_crc,
{ crc of all object/class definitions in the interface of this unit, xor'ed
by the crc's of all object/class definitions in the interfaces of units
used by this unit. Reason: see mantis #13840 }
indirect_crc : cardinal;
error,
do_crc,
do_interface_crc : boolean;
do_interface_crc,
do_indirect_crc : boolean;
crc_only : boolean; { used to calculate interface_crc before implementation }
constructor Create(const fn:string);
destructor Destroy;override;
@ -432,6 +439,7 @@ begin
header.size := swapendian(header.size);
header.checksum := swapendian(header.checksum);
header.interface_checksum := swapendian(header.interface_checksum);
header.indirect_checksum := swapendian(header.indirect_checksum);
header.deflistsize:=swapendian(header.deflistsize);
header.symlistsize:=swapendian(header.symlistsize);
{$ENDIF}
@ -847,7 +855,9 @@ begin
{reset}
crc:=0;
interface_crc:=0;
indirect_crc:=0;
do_interface_crc:=true;
do_indirect_crc:=false;
Error:=false;
do_crc:=true;
size:=0;
@ -881,6 +891,7 @@ begin
header.size := swapendian(header.size);
header.checksum := swapendian(header.checksum);
header.interface_checksum := swapendian(header.interface_checksum);
header.indirect_checksum := swapendian(header.indirect_checksum);
header.deflistsize:=swapendian(header.deflistsize);
header.symlistsize:=swapendian(header.symlistsize);
{$endif not FPC_BIG_ENDIAN}
@ -1031,6 +1042,11 @@ begin
inc(crcindex);
end;
{$endif def Test_Double_checksum}
{ indirect crc must only be calculated for the interface; changes
to a class in the implementation cannot require another unit to
be recompiled }
if do_indirect_crc then
indirect_crc:=UpdateCrc32(indirect_crc,b,len);
end;
end;
if not crc_only then

View File

@ -3976,7 +3976,17 @@ implementation
i : longint;
vmtentry : pvmtentry;
ImplIntf : TImplementedInterface;
old_do_indirect_crc: boolean;
begin
{ if class1 in unit A changes, and class2 in unit B inherits from it
(so unit B uses unit A), then unit B with class2 will be recompiled.
However, if there is also a class3 in unit C that only depends on
unit B, then unit C will not be recompiled because nothing changed
to the interface of unit B. Nevertheless, unit C can indirectly
depend on unit A via derefs, and these must be updated -> the
indirect crc keeps track of such changes. }
old_do_indirect_crc:=ppufile.do_indirect_crc;
ppufile.do_indirect_crc:=true;
inherited ppuwrite(ppufile);
ppufile.putbyte(byte(objecttype));
ppufile.putstring(objrealname^);
@ -4027,6 +4037,8 @@ implementation
if not(df_copied_def in defoptions) then
tObjectSymtable(symtable).ppuwrite(ppufile);
ppufile.do_indirect_crc:=old_do_indirect_crc;
end;

View File

@ -472,14 +472,15 @@ end;
procedure ReadLoadUnit;
var
ucrc,uintfcrc : cardinal;
ucrc,uintfcrc, indcrc : cardinal;
begin
while not ppufile.EndOfEntry do
begin
write('Uses unit: ',ppufile.getstring);
ucrc:=cardinal(ppufile.getlongint);
uintfcrc:=cardinal(ppufile.getlongint);
writeln(' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),')');
indcrc:=cardinal(ppufile.getlongint);
writeln(' (Crc: ',hexstr(ucrc,8),', IntfcCrc: ',hexstr(uintfcrc,8),', IndCrc: ',hexstr(indcrc,8),')');
end;
end;
@ -2408,6 +2409,7 @@ begin
Writeln('FileSize (w/o header) : ',size);
Writeln('Checksum : ',hexstr(checksum,8));
Writeln('Interface Checksum : ',hexstr(interface_checksum,8));
Writeln('Indirect Checksum : ',hexstr(indirect_checksum,8));
Writeln('Definitions stored : ',tostr(deflistsize));
Writeln('Symbols stored : ',tostr(symlistsize));
end;

View File

@ -44,6 +44,7 @@ type
fcalledvmtentriestemplist: tfpobjectlist;
{ devirtualisation information -- end }
procedure clearderefinfo;
public
destructor destroy; override;
@ -75,8 +76,7 @@ implementation
symdef,
verbose;
destructor tunitwpoinfo.destroy;
procedure tunitwpoinfo.clearderefinfo;
begin
if assigned(fcreatedobjtypesderefs) then
begin
@ -99,7 +99,11 @@ implementation
fcalledvmtentriestemplist.free;
fcalledvmtentriestemplist:=nil;
end;
end;
destructor tunitwpoinfo.destroy;
begin
clearderefinfo;
inherited destroy;
end;
@ -121,9 +125,9 @@ implementation
for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
ppufile.putderef(fmaybecreatedbyclassrefdeftypesderefs^[i]);
ppufile.putlongint(fcalledvmtentries.count);
for i:=0 to fcalledvmtentries.count-1 do
tcalledvmtentries(fcalledvmtentries[i]).ppuwrite(ppufile);
ppufile.putlongint(fcalledvmtentriestemplist.count);
for i:=0 to fcalledvmtentriestemplist.count-1 do
tcalledvmtentries(fcalledvmtentriestemplist[i]).ppuwrite(ppufile);
ppufile.writeentry(ibcreatedobjtypes);
@ -183,6 +187,10 @@ implementation
var
i: longint;
begin
{ ppuload may have already been called before -> deref info structures
may already have been allocated }
clearderefinfo;
getmem(fcreatedobjtypesderefs,fcreatedobjtypes.count*sizeof(tderef));
for i:=0 to fcreatedobjtypes.count-1 do
fcreatedobjtypesderefs^[i].build(fcreatedobjtypes[i]);
@ -195,13 +203,29 @@ implementation
for i:=0 to fmaybecreatedbyclassrefdeftypes.count-1 do
fmaybecreatedbyclassrefdeftypesderefs^[i].build(fmaybecreatedbyclassrefdeftypes[i]);
fcalledvmtentriestemplist:=tfpobjectlist.create(false);
fcalledvmtentriestemplist.count:=fcalledvmtentries.count;
for i:=0 to fcalledvmtentries.count-1 do
tcalledvmtentries(fcalledvmtentries[i]).objdefderef.build(tcalledvmtentries(fcalledvmtentries[i]).objdef);
begin
tcalledvmtentries(fcalledvmtentries[i]).buildderef;
{ necessary in case we have unit1 loads unit2, unit2 is recompiled,
then unit1 derefs unit2 -> in this case we have buildderef for unit2
-> ppuwrite for unit2 -> deref for unit2 (without a load) -> ensure
that the fcalledvmtentriestemplist, normally constructed by ppuload,
is created here as well since deref needs it }
fcalledvmtentriestemplist[i]:=tobject(fcalledvmtentries[i]);
end;
end;
procedure tunitwpoinfo.buildderefimpl;
var
i: longint;
begin
for i:=0 to fcalledvmtentriestemplist.count-1 do
begin
tcalledvmtentries(fcalledvmtentriestemplist[i]).buildderefimpl;
end;
end;
@ -210,7 +234,8 @@ implementation
i: longint;
begin
if (init_settings.genwpoptimizerswitches=[]) then
if (init_settings.genwpoptimizerswitches=[]) or
not assigned(fcalledvmtentriestemplist) then
exit;
{ don't free deref arrays immediately after use, as the types may need
@ -227,7 +252,6 @@ implementation
{ in case we are re-resolving, free previous batch }
if (fcalledvmtentries.count<>0) then
{ don't just re-deref, in case the name might have changed (?) }
fcalledvmtentries.clear;
{ allocate enough internal memory in one go }
fcalledvmtentries.capacity:=fcalledvmtentriestemplist.count;
@ -236,7 +260,7 @@ implementation
begin
with tcalledvmtentries(fcalledvmtentriestemplist[i]) do
begin
objdef:=tdef(objdefderef.resolve);
deref;
fcalledvmtentries.add(tobjectdef(objdef).vmt_mangledname,
fcalledvmtentriestemplist[i]);
end;
@ -245,7 +269,17 @@ implementation
procedure tunitwpoinfo.derefimpl;
var
i: longint;
begin
if (init_settings.genwpoptimizerswitches=[]) or
not assigned(fcalledvmtentriestemplist) then
exit;
for i:=0 to fcalledvmtentriestemplist.count-1 do
begin
tcalledvmtentries(fcalledvmtentriestemplist[i]).derefimpl;
end;
end;

11
tests/webtbs/tw13840/doit.sh Executable file
View File

@ -0,0 +1,11 @@
if [ $# != 1 ]; then
echo Usage: $0 ppc_to_test
exit 1
fi
rm *.ppu
$1 tw13840d
touch tw13840a.pp
$1 tw13840b -dchanged
$1 tw13840d -dchanged
./tw13840d

View File

@ -0,0 +1,29 @@
{ %interactive }
{ see tw13480d.pp for test instructions }
{$mode objfpc}
unit tw13840a;
interface
type
ta = class
procedure test({$ifdef changed}a: longint = 4{$endif}); virtual;
procedure mymy(var a);virtual;
end;
implementation
procedure ta.test({$ifdef changed}a: longint = 4{$endif});
begin
writeln('ta.test');
end;
procedure ta.mymy(var a);
begin
writeln('ta.mymy');
end;
end.

View File

@ -0,0 +1,26 @@
{ %interactive }
{ see tw13480d.pp for test instructions }
{$mode objfpc}
unit tw13840b;
interface
uses
tw13840a;
type
tb = class(ta)
end;
implementation
{
procedure tb.test;
begin
writeln('tb.test');
inherited test;
end;
}
end.

View File

@ -0,0 +1,27 @@
{ %interactive }
{ see tw13480d.pp for test instructions }
{$mode objfpc}
unit tw13840c;
interface
uses
tw13840b;
type
tc = class(tb)
procedure mymy(var a);override;
end;
implementation
procedure tc.mymy(var a);
begin
writeln('tc.mymy');
inherited;
end;
end.

View File

@ -0,0 +1,28 @@
{ %interactive }
{ perform the following steps:
rm tw13840d.ppu
fpc tw13840d
touch tw13840a.pp
fpc tw13840b -dchanged
fpc tw13840d -dchanged
In the last step, unit c also has to be recompiled. If it isn't, a linker
error will occur.
}
{$mode objfpc}
uses
tw13840c;
var
c: tc;
begin
c:=tc.create;
c.test;
c.mymy(c);
c.free;
end.