mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 21:10:11 +02:00
* Introduce m_processed
This commit is contained in:
parent
5298e25c84
commit
462c201ce6
@ -57,9 +57,12 @@ type
|
|||||||
public
|
public
|
||||||
constructor create;
|
constructor create;
|
||||||
destructor destroy; override;
|
destructor destroy; override;
|
||||||
|
// Find the task for module m
|
||||||
function findtask(m : tmodule) : ttask_list;
|
function findtask(m : tmodule) : ttask_list;
|
||||||
// Can we continue processing this module ?
|
// Can we continue processing this module ? If not, firstwaiting contains first module that m is waiting for.
|
||||||
function cancontinue(t : ttask_list) : boolean;
|
function cancontinue(m : tmodule; checksub : boolean; out firstwaiting: tmodule): boolean;
|
||||||
|
// Overload of cancontinue, based on task.
|
||||||
|
function cancontinue(t: ttask_list; out firstwaiting: tmodule): boolean; inline
|
||||||
// Continue processing this module. Return true if the module is done and can be removed.
|
// Continue processing this module. Return true if the module is done and can be removed.
|
||||||
function continue(t : ttask_list): Boolean;
|
function continue(t : ttask_list): Boolean;
|
||||||
// process the queue. Note that while processing the queue, elements will be added.
|
// process the queue. Note that while processing the queue, elements will be added.
|
||||||
@ -77,7 +80,7 @@ procedure DoneTaskHandler;
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses verbose, finput, globtype, sysutils, scanner, parser, pmodules;
|
uses verbose, fppu, finput, globtype, sysutils, scanner, parser, pmodules;
|
||||||
|
|
||||||
procedure InitTaskHandler;
|
procedure InitTaskHandler;
|
||||||
begin
|
begin
|
||||||
@ -126,22 +129,21 @@ end;
|
|||||||
procedure ttask_list.SaveState;
|
procedure ttask_list.SaveState;
|
||||||
begin
|
begin
|
||||||
if State=Nil then
|
if State=Nil then
|
||||||
State:=tglobalstate.Create(true);
|
State:=tglobalstate.Create(true)
|
||||||
|
else
|
||||||
|
State.save(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ttask_list.RestoreState;
|
procedure ttask_list.RestoreState;
|
||||||
begin
|
begin
|
||||||
if not module.is_reset then
|
if not module.is_reset then
|
||||||
state.restore(true);
|
state.restore(true);
|
||||||
|
|
||||||
if assigned(current_scanner) and assigned(current_scanner.inputfile) then
|
if assigned(current_scanner) and assigned(current_scanner.inputfile) then
|
||||||
if current_scanner.inputfile.closed then
|
if current_scanner.inputfile.closed then
|
||||||
begin
|
begin
|
||||||
current_scanner.tempopeninputfile;
|
current_scanner.tempopeninputfile;
|
||||||
current_scanner.gettokenpos;
|
current_scanner.gettokenpos;
|
||||||
// parser_current_file:=current_scanner.inputfile.name;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ ttask_handler }
|
{ ttask_handler }
|
||||||
@ -172,25 +174,63 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ttask_handler.cancontinue(t : ttask_list): boolean;
|
function ttask_handler.cancontinue(m: tmodule; checksub : boolean; out firstwaiting: tmodule): boolean;
|
||||||
|
|
||||||
|
procedure CheckUsed(out acandidate : tmodule);
|
||||||
|
|
||||||
|
var
|
||||||
|
itm : TLinkedListItem;
|
||||||
|
iscandidate : boolean;
|
||||||
|
m2 : tmodule;
|
||||||
|
|
||||||
|
begin
|
||||||
|
acandidate:=nil;
|
||||||
|
itm:=m.used_units.First;
|
||||||
|
while (acandidate=Nil) and assigned(itm) do
|
||||||
|
begin
|
||||||
|
iscandidate:=Not (tused_unit(itm).u.state in [ms_compiled]);
|
||||||
|
if iscandidate then
|
||||||
|
begin
|
||||||
|
acandidate:=tused_unit(itm).u;
|
||||||
|
if not cancontinue(acandidate,false,m2) then
|
||||||
|
acandidate:=nil;
|
||||||
|
end;
|
||||||
|
itm:=itm.Next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
m : tmodule;
|
m2 : tmodule;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
m:=t.module;
|
firstwaiting:=nil;
|
||||||
|
if m.is_initial and (list.count>1) then
|
||||||
|
exit(False);
|
||||||
case m.state of
|
case m.state of
|
||||||
ms_unknown : cancontinue:=true;
|
ms_unknown : cancontinue:=true;
|
||||||
ms_registered : cancontinue:=true;
|
ms_registered : cancontinue:=true;
|
||||||
ms_compile : cancontinue:=true;
|
ms_compile : cancontinue:=true;
|
||||||
ms_compiling_waitimpl : cancontinue:=m.usedunitsloaded(false);
|
ms_compiling_waitimpl : cancontinue:=m.usedunitsloaded(false,firstwaiting);
|
||||||
ms_compiling_waitintf : cancontinue:=m.usedunitsloaded(true);
|
ms_compiling_waitintf : cancontinue:=m.usedunitsloaded(true,firstwaiting);
|
||||||
ms_compiling_wait : cancontinue:=m.usedunitsloaded(true);
|
ms_compiling_wait : cancontinue:=m.usedunitsloaded(true,firstwaiting);
|
||||||
ms_compiled : cancontinue:=true;
|
ms_compiled : cancontinue:=true;
|
||||||
|
ms_processed : cancontinue:=true;
|
||||||
ms_moduleerror : cancontinue:=true;
|
ms_moduleerror : cancontinue:=true;
|
||||||
else
|
else
|
||||||
InternalError(2024011802);
|
InternalError(2024011802);
|
||||||
end;
|
end;
|
||||||
|
if (not cancontinue) and checksub then
|
||||||
|
begin
|
||||||
|
checkused(m2);
|
||||||
|
if m2<>nil then
|
||||||
|
firstwaiting:=m2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ttask_handler.cancontinue(t : ttask_list; out firstwaiting : tmodule): boolean;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Result:=cancontinue(t.module,true,firstwaiting);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ttask_handler.continue(t : ttask_list) : Boolean;
|
function ttask_handler.continue(t : ttask_list) : Boolean;
|
||||||
@ -205,14 +245,23 @@ begin
|
|||||||
case m.state of
|
case m.state of
|
||||||
ms_registered : parser.compile_module(m);
|
ms_registered : parser.compile_module(m);
|
||||||
ms_compile : parser.compile_module(m);
|
ms_compile : parser.compile_module(m);
|
||||||
|
ms_compiled : if (not m.is_initial) or m.is_unit then
|
||||||
|
(m as tppumodule).post_load_or_compile(m.compilecount>1);
|
||||||
ms_compiling_waitintf : pmodules.parse_unit_interface_declarations(m);
|
ms_compiling_waitintf : pmodules.parse_unit_interface_declarations(m);
|
||||||
ms_compiling_waitimpl : pmodules.proc_unit_implementation(m);
|
ms_compiling_waitimpl : pmodules.proc_unit_implementation(m);
|
||||||
ms_compiling_wait : pmodules.proc_program_declarations(m,m.islibrary);
|
ms_compiling_wait : pmodules.proc_program_declarations(m,m.islibrary);
|
||||||
|
ms_processed : ;
|
||||||
else
|
else
|
||||||
InternalError(2024011801);
|
InternalError(2024011801);
|
||||||
end;
|
end;
|
||||||
Result:=m.state=ms_compiled;
|
if m.state=ms_compiled then
|
||||||
if not Result then
|
begin
|
||||||
|
parsing_done(m);
|
||||||
|
if m.is_initial and not m.is_unit then
|
||||||
|
m.state:=ms_processed;
|
||||||
|
end;
|
||||||
|
Result:=m.state=ms_processed;
|
||||||
|
if not result then
|
||||||
// Not done, save state
|
// Not done, save state
|
||||||
t.SaveState;
|
t.SaveState;
|
||||||
end;
|
end;
|
||||||
@ -220,14 +269,15 @@ end;
|
|||||||
procedure ttask_handler.processqueue;
|
procedure ttask_handler.processqueue;
|
||||||
|
|
||||||
var
|
var
|
||||||
t : ttask_list;
|
t,t2 : ttask_list;
|
||||||
process : boolean;
|
process : boolean;
|
||||||
|
m,firstwaiting : tmodule;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
t:=list.firsttask;
|
t:=list.firsttask;
|
||||||
While t<>nil do
|
While t<>nil do
|
||||||
begin
|
begin
|
||||||
process:=cancontinue(t);
|
process:=cancontinue(t,firstwaiting);
|
||||||
if process then
|
if process then
|
||||||
begin
|
begin
|
||||||
if continue(t) then
|
if continue(t) then
|
||||||
@ -238,14 +288,22 @@ begin
|
|||||||
// maybe the strategy can be improved.
|
// maybe the strategy can be improved.
|
||||||
t:=list.firsttask;
|
t:=list.firsttask;
|
||||||
end
|
end
|
||||||
|
else if assigned(firstwaiting) and cancontinue(firstwaiting,true, m) then
|
||||||
|
begin
|
||||||
|
t2:=findtask(firstwaiting);
|
||||||
|
if t2=nil then
|
||||||
|
t2:=t.nexttask;
|
||||||
|
t:=t2;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
t:=t.nexttask;
|
t:=t.nexttask;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ttask_handler.addmodule(m: tmodule);
|
procedure ttask_handler.addmodule(m: tmodule);
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
n : TSymStr;
|
n : TSymStr;
|
||||||
e : tmodule;
|
e : tmodule;
|
||||||
@ -265,7 +323,6 @@ begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// We have a task, if it was reset, then clear the state and move the task to the start.
|
// We have a task, if it was reset, then clear the state and move the task to the start.
|
||||||
|
|
||||||
if m.is_reset then
|
if m.is_reset then
|
||||||
begin
|
begin
|
||||||
m.is_reset:=false;
|
m.is_reset:=false;
|
||||||
|
@ -123,8 +123,11 @@ interface
|
|||||||
ms_compiling_waitimpl,
|
ms_compiling_waitimpl,
|
||||||
ms_compiling_wait,
|
ms_compiling_wait,
|
||||||
ms_compiled,
|
ms_compiled,
|
||||||
|
ms_processed,
|
||||||
ms_moduleerror
|
ms_moduleerror
|
||||||
);
|
);
|
||||||
|
tmodulestates = set of tmodulestate;
|
||||||
|
|
||||||
const
|
const
|
||||||
ModuleStateStr : array[TModuleState] of string[32] = (
|
ModuleStateStr : array[TModuleState] of string[32] = (
|
||||||
'Unknown',
|
'Unknown',
|
||||||
@ -135,6 +138,7 @@ interface
|
|||||||
'Compiling_Waiting_implementation',
|
'Compiling_Waiting_implementation',
|
||||||
'Compiling_Waiting',
|
'Compiling_Waiting',
|
||||||
'Compiled',
|
'Compiled',
|
||||||
|
'Processed',
|
||||||
'Error'
|
'Error'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -30,8 +30,9 @@ uses fmodule;
|
|||||||
{$ifdef PREPROCWRITE}
|
{$ifdef PREPROCWRITE}
|
||||||
procedure preprocess(const filename:string);
|
procedure preprocess(const filename:string);
|
||||||
{$endif PREPROCWRITE}
|
{$endif PREPROCWRITE}
|
||||||
procedure compile(const filename:string);
|
function compile(const filename:string) : boolean;
|
||||||
procedure compile_module(module : tmodule);
|
function compile_module(module : tmodule) : boolean;
|
||||||
|
procedure parsing_done(module : tmodule);
|
||||||
procedure initparser;
|
procedure initparser;
|
||||||
procedure doneparser;
|
procedure doneparser;
|
||||||
|
|
||||||
@ -54,6 +55,71 @@ implementation
|
|||||||
pbase,psystem,pmodules,psub,ncgrtti,
|
pbase,psystem,pmodules,psub,ncgrtti,
|
||||||
cpuinfo,procinfo;
|
cpuinfo,procinfo;
|
||||||
|
|
||||||
|
procedure parsing_done(module: tmodule);
|
||||||
|
|
||||||
|
var
|
||||||
|
hp,hp2 : tmodule;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
module.end_of_parsing;
|
||||||
|
|
||||||
|
if (module.is_initial) and
|
||||||
|
(status.errorcount=0) then
|
||||||
|
{ Write Browser Collections }
|
||||||
|
do_extractsymbolinfo;
|
||||||
|
|
||||||
|
// olddata.restore(false);
|
||||||
|
|
||||||
|
{ Restore all locally modified warning messages }
|
||||||
|
RestoreLocalVerbosity(current_settings.pmessage);
|
||||||
|
current_exceptblock:=0;
|
||||||
|
exceptblockcounter:=0;
|
||||||
|
|
||||||
|
{ Shut down things when the last file is compiled succesfull }
|
||||||
|
if (module.is_initial) and (module.state=ms_compiled) and
|
||||||
|
(status.errorcount=0) then
|
||||||
|
begin
|
||||||
|
parser_current_file:='';
|
||||||
|
{ Close script }
|
||||||
|
if (not AsmRes.Empty) then
|
||||||
|
begin
|
||||||
|
Message1(exec_i_closing_script,AsmRes.Fn);
|
||||||
|
AsmRes.WriteToDisk;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ free now what we did not free earlier in
|
||||||
|
proc_program PM }
|
||||||
|
if (module.is_initial) and (module.state=ms_compiled) and needsymbolinfo then
|
||||||
|
begin
|
||||||
|
hp:=tmodule(loaded_units.first);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
hp2:=tmodule(hp.next);
|
||||||
|
if (hp<>module) then
|
||||||
|
begin
|
||||||
|
loaded_units.remove(hp);
|
||||||
|
hp.free;
|
||||||
|
end;
|
||||||
|
hp:=hp2;
|
||||||
|
end;
|
||||||
|
{ free also unneeded units we didn't free before }
|
||||||
|
unloaded_units.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ If used units are compiled current_module is already the same as
|
||||||
|
the stored module. Now if the unit is not finished its scanner is
|
||||||
|
not yet freed and thus set_current_module would reopen the scanned
|
||||||
|
file which will result in pointing to the wrong position in the
|
||||||
|
file. In the normal case current_scanner and current_module.scanner
|
||||||
|
would be Nil, thus nothing bad would happen }
|
||||||
|
{ if olddata.old_current_module<>current_module then
|
||||||
|
set_current_module(olddata.old_current_module);}
|
||||||
|
|
||||||
|
FreeLocalVerbosity(current_settings.pmessage);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
procedure initparser;
|
procedure initparser;
|
||||||
begin
|
begin
|
||||||
@ -321,27 +387,26 @@ implementation
|
|||||||
Compile a source file
|
Compile a source file
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
procedure compile(const filename:string);
|
function compile(const filename:string) : boolean;
|
||||||
|
|
||||||
var
|
var
|
||||||
m : TModule;
|
m : TModule;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
m:=tppumodule.create(nil,'',filename,false);
|
m:=tppumodule.create(nil,'',filename,false);
|
||||||
// m.is_initial:=initial;
|
|
||||||
m.state:=ms_compile;
|
m.state:=ms_compile;
|
||||||
compile_module(m);
|
result:=compile_module(m);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure compile_module(module : tmodule);
|
function compile_module(module : tmodule) : boolean;
|
||||||
|
|
||||||
var
|
var
|
||||||
olddata : tglobalstate;
|
|
||||||
hp,hp2 : tmodule;
|
hp,hp2 : tmodule;
|
||||||
finished : boolean;
|
finished : boolean;
|
||||||
sc : tscannerfile;
|
sc : tscannerfile;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Result:=True;
|
||||||
{ parsing a procedure or declaration should be finished }
|
{ parsing a procedure or declaration should be finished }
|
||||||
if assigned(current_procinfo) then
|
if assigned(current_procinfo) then
|
||||||
internalerror(200811121);
|
internalerror(200811121);
|
||||||
@ -354,7 +419,6 @@ implementation
|
|||||||
recursively }
|
recursively }
|
||||||
{ handle the postponed case first }
|
{ handle the postponed case first }
|
||||||
flushpendingswitchesstate;
|
flushpendingswitchesstate;
|
||||||
olddata:=tglobalstate.create(false);
|
|
||||||
|
|
||||||
{ reset parser, a previous fatal error could have left these variables in an unreliable state, this is
|
{ reset parser, a previous fatal error could have left these variables in an unreliable state, this is
|
||||||
important for the IDE }
|
important for the IDE }
|
||||||
@ -431,10 +495,10 @@ implementation
|
|||||||
else if (token=_ID) and (idtoken=_PACKAGE) then
|
else if (token=_ID) and (idtoken=_PACKAGE) then
|
||||||
begin
|
begin
|
||||||
module.IsPackage:=true;
|
module.IsPackage:=true;
|
||||||
proc_package(module);
|
finished:=proc_package(module);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
proc_program(module,token=_LIBRARY);
|
finished:=proc_program(module,token=_LIBRARY);
|
||||||
except
|
except
|
||||||
on ECompilerAbort do
|
on ECompilerAbort do
|
||||||
raise;
|
raise;
|
||||||
@ -451,83 +515,14 @@ implementation
|
|||||||
raise;
|
raise;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Result:=Finished;
|
||||||
{ the program or the unit at the command line should not need to wait
|
{ the program or the unit at the command line should not need to wait
|
||||||
for other units }
|
for other units }
|
||||||
if (module.is_initial) and not finished then
|
// if (module.is_initial) and not finished then
|
||||||
internalerror(2012091901);
|
// internalerror(2012091901);
|
||||||
finally
|
finally
|
||||||
if assigned(module) then
|
|
||||||
begin
|
|
||||||
if finished then
|
if finished then
|
||||||
module.end_of_parsing
|
parsing_done(module);
|
||||||
else
|
|
||||||
begin
|
|
||||||
{ these are saved in the unit's state and thus can be set to
|
|
||||||
Nil again as would be done by tmodule.end_of_parsing }
|
|
||||||
macrosymtablestack:=nil;
|
|
||||||
symtablestack:=nil;
|
|
||||||
if current_scanner=current_module.scanner then
|
|
||||||
set_current_scanner(nil);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (module.is_initial) and
|
|
||||||
(status.errorcount=0) then
|
|
||||||
{ Write Browser Collections }
|
|
||||||
do_extractsymbolinfo;
|
|
||||||
|
|
||||||
olddata.restore(false);
|
|
||||||
|
|
||||||
{ Restore all locally modified warning messages }
|
|
||||||
RestoreLocalVerbosity(current_settings.pmessage);
|
|
||||||
current_exceptblock:=0;
|
|
||||||
exceptblockcounter:=0;
|
|
||||||
|
|
||||||
{ Shut down things when the last file is compiled succesfull }
|
|
||||||
if (module.is_initial) and
|
|
||||||
(status.errorcount=0) then
|
|
||||||
begin
|
|
||||||
parser_current_file:='';
|
|
||||||
{ Close script }
|
|
||||||
if (not AsmRes.Empty) then
|
|
||||||
begin
|
|
||||||
Message1(exec_i_closing_script,AsmRes.Fn);
|
|
||||||
AsmRes.WriteToDisk;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ free now what we did not free earlier in
|
|
||||||
proc_program PM }
|
|
||||||
if (module.is_initial) and needsymbolinfo then
|
|
||||||
begin
|
|
||||||
hp:=tmodule(loaded_units.first);
|
|
||||||
while assigned(hp) do
|
|
||||||
begin
|
|
||||||
hp2:=tmodule(hp.next);
|
|
||||||
if (hp<>module) then
|
|
||||||
begin
|
|
||||||
loaded_units.remove(hp);
|
|
||||||
hp.free;
|
|
||||||
end;
|
|
||||||
hp:=hp2;
|
|
||||||
end;
|
|
||||||
{ free also unneeded units we didn't free before }
|
|
||||||
unloaded_units.Clear;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ If used units are compiled current_module is already the same as
|
|
||||||
the stored module. Now if the unit is not finished its scanner is
|
|
||||||
not yet freed and thus set_current_module would reopen the scanned
|
|
||||||
file which will result in pointing to the wrong position in the
|
|
||||||
file. In the normal case current_scanner and current_module.scanner
|
|
||||||
would be Nil, thus nothing bad would happen }
|
|
||||||
if olddata.old_current_module<>current_module then
|
|
||||||
set_current_module(olddata.old_current_module);
|
|
||||||
|
|
||||||
FreeLocalVerbosity(current_settings.pmessage);
|
|
||||||
|
|
||||||
FreeAndNil(olddata);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -3029,7 +3029,7 @@ type
|
|||||||
if assigned(onfreescanner) then
|
if assigned(onfreescanner) then
|
||||||
onfreescanner(self);
|
onfreescanner(self);
|
||||||
if assigned(current_module) and
|
if assigned(current_module) and
|
||||||
(current_module.state=ms_compiled) and
|
(current_module.state in [ms_processed,ms_compiled]) and
|
||||||
(status.errorcount=0) then
|
(status.errorcount=0) then
|
||||||
checkpreprocstack
|
checkpreprocstack
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user