Browse Source

* Move implementation part to separate routine so we can split tasks later

Michaël Van Canneyt 1 year ago
parent
commit
560d597c85
1 changed files with 162 additions and 136 deletions
  1. 162 136
      compiler/pmodules.pas

+ 162 - 136
compiler/pmodules.pas

@@ -48,7 +48,7 @@ implementation
        objcgutl,
        objcgutl,
        pkgutil,
        pkgutil,
        wpobase,
        wpobase,
-       scanner,pbase,pexpr,psystem,psub,pdecsub,pgenutil,pparautl,ncgvmt,ncgrtti,
+       scanner,pbase,pexpr,psystem,psub,pgenutil,pparautl,ncgvmt,ncgrtti,
        cpuinfo;
        cpuinfo;
 
 
 
 
@@ -481,83 +481,95 @@ implementation
         until false;
         until false;
       end;
       end;
 
 
+    procedure parseusesclause(curr: tmodule);
 
 
-    procedure loadunits(curr: tmodule; preservest:tsymtable);
       var
       var
          s,sorg  : ansistring;
          s,sorg  : ansistring;
          fn      : string;
          fn      : string;
-         pu,pu2  : tused_unit;
+         pu  : tused_unit;
          hp2     : tmodule;
          hp2     : tmodule;
          unitsym : tunitsym;
          unitsym : tunitsym;
          filepos : tfileposinfo;
          filepos : tfileposinfo;
+
       begin
       begin
-         consume(_USES);
-         repeat
-           s:=pattern;
-           sorg:=orgpattern;
-           filepos:=current_tokenpos;
-           consume(_ID);
-           while token=_POINT do
-             begin
-               consume(_POINT);
-               s:=s+'.'+pattern;
-               sorg:=sorg+'.'+orgpattern;
-               consume(_ID);
-             end;
-           { support "<unit> in '<file>'" construct, but not for tp7 }
-           fn:='';
-           if not(m_tp7 in current_settings.modeswitches) and
-              try_to_consume(_OP_IN) then
-             fn:=FixFileName(get_stringconst);
-           { Give a warning if lineinfo is loaded }
-           if s='LINEINFO' then
-             begin
-               Message(parser_w_no_lineinfo_use_switch);
-               if (target_dbg.id in [dbg_dwarf2, dbg_dwarf3]) then
-                s := 'LNFODWRF';
-              sorg := s;
-             end;
-           { Give a warning if objpas is loaded }
-           if s='OBJPAS' then
-            Message(parser_w_no_objpas_use_mode);
-           { Using the unit itself is not possible }
-           if (s<>curr.modulename^) then
+        consume(_USES);
+        repeat
+          s:=pattern;
+          sorg:=orgpattern;
+          filepos:=current_tokenpos;
+          consume(_ID);
+          while token=_POINT do
             begin
             begin
-              { check if the unit is already used }
-              hp2:=nil;
-              pu:=tused_unit(curr.used_units.first);
-              while assigned(pu) do
-               begin
-                 if (pu.u.modulename^=s) then
-                  begin
-                    hp2:=pu.u;
-                    break;
-                  end;
-                 pu:=tused_unit(pu.next);
-               end;
-              if not assigned(hp2) then
-                hp2:=registerunit(curr,sorg,fn)
-              else
-                Message1(sym_e_duplicate_id,s);
-              { Create unitsym, we need to use the name as specified, we
-                can not use the modulename because that can be different
-                when -Un is used }
-              current_tokenpos:=filepos;
-              unitsym:=cunitsym.create(sorg,nil);
-              { the current module uses the unit hp2 }
-              curr.addusedunit(hp2,true,unitsym);
-            end
-           else
-            Message1(sym_e_duplicate_id,s);
-           if token=_COMMA then
+              consume(_POINT);
+              s:=s+'.'+pattern;
+              sorg:=sorg+'.'+orgpattern;
+              consume(_ID);
+            end;
+          { support "<unit> in '<file>'" construct, but not for tp7 }
+          fn:='';
+          if not(m_tp7 in current_settings.modeswitches) and
+             try_to_consume(_OP_IN) then
+            fn:=FixFileName(get_stringconst);
+          { Give a warning if lineinfo is loaded }
+          if s='LINEINFO' then
             begin
             begin
-              pattern:='';
-              consume(_COMMA);
-            end
-           else
-            break;
-         until false;
+              Message(parser_w_no_lineinfo_use_switch);
+              if (target_dbg.id in [dbg_dwarf2, dbg_dwarf3]) then
+               s := 'LNFODWRF';
+             sorg := s;
+            end;
+          { Give a warning if objpas is loaded }
+          if s='OBJPAS' then
+           Message(parser_w_no_objpas_use_mode);
+          { Using the unit itself is not possible }
+          if (s<>curr.modulename^) then
+           begin
+             { check if the unit is already used }
+             hp2:=nil;
+             pu:=tused_unit(curr.used_units.first);
+             while assigned(pu) do
+              begin
+                if (pu.u.modulename^=s) then
+                 begin
+                   hp2:=pu.u;
+                   break;
+                 end;
+                pu:=tused_unit(pu.next);
+              end;
+             if not assigned(hp2) then
+               hp2:=registerunit(curr,sorg,fn)
+             else
+               Message1(sym_e_duplicate_id,s);
+             { Create unitsym, we need to use the name as specified, we
+               can not use the modulename because that can be different
+               when -Un is used }
+             current_tokenpos:=filepos;
+             unitsym:=cunitsym.create(sorg,nil);
+             { the current module uses the unit hp2 }
+             curr.addusedunit(hp2,true,unitsym);
+           end
+          else
+           Message1(sym_e_duplicate_id,s);
+          if token=_COMMA then
+           begin
+             pattern:='';
+             consume(_COMMA);
+           end
+          else
+           break;
+        until false;
+      end;
+
+
+    procedure loadunits(curr: tmodule; preservest:tsymtable);
 
 
+      var
+         s,sorg  : ansistring;
+         pu,pu2  : tused_unit;
+         hp2     : tmodule;
+
+      begin
+         parseusesclause(curr);
          { Load the units }
          { Load the units }
          pu:=tused_unit(curr.used_units.first);
          pu:=tused_unit(curr.used_units.first);
          while assigned(pu) do
          while assigned(pu) do
@@ -894,27 +906,100 @@ type
     end;
     end;
     pfinishstate=^tfinishstate;
     pfinishstate=^tfinishstate;
 
 
+
     procedure finish_unit(module:tmodule;immediate:boolean);forward;
     procedure finish_unit(module:tmodule;immediate:boolean);forward;
 
 
+    function proc_unit_implementation(curr: tmodule):boolean;
+
+      var
+        init_procinfo,
+        finalize_procinfo : tcgprocinfo;
+        i,j : integer;
+        finishstate:pfinishstate;
+        globalstate:pglobalstate;
+
+      begin
+        result:=true;
+        init_procinfo:=nil;
+        finalize_procinfo:=nil;
+        finishstate:=nil;
+        globalstate:=nil;
+
+
+        { All units are read, now give them a number }
+        curr.updatemaps;
+
+        { further, changing the globalsymtable is not allowed anymore }
+        curr.globalsymtable.sealed:=true;
+        symtablestack.push(curr.localsymtable);
+
+        if not curr.interface_only then
+          begin
+            Message1(parser_u_parsing_implementation,curr.modulename^);
+            if curr.in_interface then
+              internalerror(200212285);
+
+            { Compile the unit }
+            init_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'init$'),potype_unitinit,curr.localsymtable);
+            init_procinfo.procdef.aliasnames.concat(make_mangledname('INIT$',curr.localsymtable,''));
+            init_procinfo.parse_body;
+            { save file pos for debuginfo }
+            curr.mainfilepos:=init_procinfo.entrypos;
+
+            { parse finalization section }
+            if token=_FINALIZATION then
+              begin
+                { Compile the finalize }
+                finalize_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'finalize$'),potype_unitfinalize,curr.localsymtable);
+                finalize_procinfo.procdef.aliasnames.concat(make_mangledname('FINALIZE$',curr.localsymtable,''));
+                finalize_procinfo.parse_body;
+              end
+          end;
+
+        { remove all units that we are waiting for that are already waiting for
+          us => breaking up circles }
+        for i:=0 to curr.waitingunits.count-1 do
+          for j:=curr.waitingforunit.count-1 downto 0 do
+            if curr.waitingunits[i]=curr.waitingforunit[j] then
+              curr.waitingforunit.delete(j);
+
+    {$ifdef DEBUG_UNITWAITING}
+        Writeln('Units waiting for ', curr.modulename^, ': ',
+          curr.waitingforunit.Count);
+    {$endif}
+        result:=curr.waitingforunit.count=0;
+
+        { save all information that is needed for finishing the unit }
+        New(finishstate);
+        finishstate^.init_procinfo:=init_procinfo;
+        finishstate^.finalize_procinfo:=finalize_procinfo;
+        curr.finishstate:=finishstate;
+
+        if result then
+          finish_unit(curr,true)
+        else
+          begin
+            { save the current state, so the parsing can continue where we left
+              of here }
+            New(globalstate);
+            save_global_state(globalstate^,true);
+            curr.globalstate:=globalstate;
+          end;
+      end;
+
+
     function proc_unit(curr: tmodule):boolean;
     function proc_unit(curr: tmodule):boolean;
       var
       var
          main_file: tinputfile;
          main_file: tinputfile;
          s1,s2  : ^string; {Saves stack space}
          s1,s2  : ^string; {Saves stack space}
-         finalize_procinfo,
-         init_procinfo : tcgprocinfo;
          unitname : ansistring;
          unitname : ansistring;
          unitname8 : string[8];
          unitname8 : string[8];
-         i,j : longint;
-         finishstate:pfinishstate;
-         globalstate:pglobalstate;
          consume_semicolon_after_uses:boolean;
          consume_semicolon_after_uses:boolean;
          feature : tfeature;
          feature : tfeature;
+
       begin
       begin
          result:=true;
          result:=true;
 
 
-         init_procinfo:=nil;
-         finalize_procinfo:=nil;
-
          if m_mac in current_settings.modeswitches then
          if m_mac in current_settings.modeswitches then
            curr.mode_switch_allowed:= false;
            curr.mode_switch_allowed:= false;
 
 
@@ -1137,66 +1222,7 @@ type
              symtablestack.pop(curr.globalsymtable);
              symtablestack.pop(curr.globalsymtable);
              exit;
              exit;
            end;
            end;
-
-         { All units are read, now give them a number }
-         curr.updatemaps;
-
-         { further, changing the globalsymtable is not allowed anymore }
-         curr.globalsymtable.sealed:=true;
-         symtablestack.push(curr.localsymtable);
-
-         if not curr.interface_only then
-           begin
-             Message1(parser_u_parsing_implementation,curr.modulename^);
-             if curr.in_interface then
-               internalerror(200212285);
-
-             { Compile the unit }
-             init_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'init$'),potype_unitinit,curr.localsymtable);
-             init_procinfo.procdef.aliasnames.concat(make_mangledname('INIT$',curr.localsymtable,''));
-             init_procinfo.parse_body;
-             { save file pos for debuginfo }
-             curr.mainfilepos:=init_procinfo.entrypos;
-
-             { parse finalization section }
-             if token=_FINALIZATION then
-               begin
-                 { Compile the finalize }
-                 finalize_procinfo:=create_main_proc(make_mangledname('',curr.localsymtable,'finalize$'),potype_unitfinalize,curr.localsymtable);
-                 finalize_procinfo.procdef.aliasnames.concat(make_mangledname('FINALIZE$',curr.localsymtable,''));
-                 finalize_procinfo.parse_body;
-               end
-           end;
-
-         { remove all units that we are waiting for that are already waiting for
-           us => breaking up circles }
-         for i:=0 to curr.waitingunits.count-1 do
-           for j:=curr.waitingforunit.count-1 downto 0 do
-             if curr.waitingunits[i]=curr.waitingforunit[j] then
-               curr.waitingforunit.delete(j);
-
-{$ifdef DEBUG_UNITWAITING}
-         Writeln('Units waiting for ', curr.modulename^, ': ',
-           curr.waitingforunit.Count);
-{$endif}
-         result:=curr.waitingforunit.count=0;
-
-         { save all information that is needed for finishing the unit }
-         New(finishstate);
-         finishstate^.init_procinfo:=init_procinfo;
-         finishstate^.finalize_procinfo:=finalize_procinfo;
-         curr.finishstate:=finishstate;
-
-         if result then
-           finish_unit(curr,true)
-         else
-           begin
-             { save the current state, so the parsing can continue where we left
-               of here }
-             New(globalstate);
-             save_global_state(globalstate^,true);
-             curr.globalstate:=globalstate;
-           end;
+         result:=proc_unit_implementation(curr);
       end;
       end;
 
 
     procedure finish_unit(module:tmodule;immediate:boolean);
     procedure finish_unit(module:tmodule;immediate:boolean);
@@ -1240,7 +1266,7 @@ type
         globalstate : tglobalstate;
         globalstate : tglobalstate;
         waitingmodule : tmodule;
         waitingmodule : tmodule;
       begin
       begin
-         fillchar(globalstate,sizeof(tglobalstate),0);
+          globalstate:=default(tglobalstate);
          if not immediate then
          if not immediate then
            begin
            begin
 {$ifdef DEBUG_UNITWAITING}
 {$ifdef DEBUG_UNITWAITING}