Browse Source

* procvar cleanup

peter 21 years ago
parent
commit
c844c5a505

+ 9 - 2
compiler/nadd.pas

@@ -74,7 +74,7 @@ implementation
       symconst,symtype,symdef,symsym,symtable,defutil,defcmp,
       symconst,symtype,symdef,symsym,symtable,defutil,defcmp,
       cgbase,
       cgbase,
       htypechk,pass_1,
       htypechk,pass_1,
-      nbas,nmat,ncnv,ncon,nset,nopt,ncal,ninl,nmem,
+      nbas,nmat,ncnv,ncon,nset,nopt,ncal,ninl,nmem,nutils,
       {$ifdef state_tracking}
       {$ifdef state_tracking}
       nstate,
       nstate,
       {$endif}
       {$endif}
@@ -128,6 +128,10 @@ implementation
          if codegenerror then
          if codegenerror then
            exit;
            exit;
 
 
+         { tp procvar support }
+         maybe_call_procvar(left,true);
+         maybe_call_procvar(right,true);
+
          { convert array constructors to sets, because there is no other operator
          { convert array constructors to sets, because there is no other operator
            possible for array constructors }
            possible for array constructors }
          if is_array_constructor(left.resulttype.def) then
          if is_array_constructor(left.resulttype.def) then
@@ -1910,7 +1914,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.110  2004-02-05 01:24:08  florian
+  Revision 1.111  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.110  2004/02/05 01:24:08  florian
     * several fixes to compile x86-64 system
     * several fixes to compile x86-64 system
 
 
   Revision 1.109  2004/02/03 22:32:54  peter
   Revision 1.109  2004/02/03 22:32:54  peter

+ 68 - 28
compiler/ncal.pas

@@ -194,7 +194,7 @@ implementation
       verbose,globals,
       verbose,globals,
       symconst,defutil,defcmp,
       symconst,defutil,defcmp,
       htypechk,pass_1,
       htypechk,pass_1,
-      ncnv,nld,ninl,nadd,ncon,nmem,
+      ncnv,nld,ninl,nadd,ncon,nmem,nutils,
       procinfo,
       procinfo,
       cgbase
       cgbase
       ;
       ;
@@ -597,6 +597,16 @@ type
 
 
          if (left.nodetype<>nothingn) then
          if (left.nodetype<>nothingn) then
            begin
            begin
+             { Convert tp procvars, this is needs to be done
+               here to make the change permanent. in the overload
+               choosing the changes are only made temporary }
+             if (left.resulttype.def.deftype=procvardef) and
+                (paraitem.paratype.def.deftype<>procvardef) then
+               begin
+                 if maybe_call_procvar(left,true) then
+                   resulttype:=left.resulttype;
+               end;
+
              { Handle varargs and hidden paras directly, no typeconvs or }
              { Handle varargs and hidden paras directly, no typeconvs or }
              { typechecking needed                                       }
              { typechecking needed                                       }
              if (nf_varargs_para in flags) then
              if (nf_varargs_para in flags) then
@@ -1468,10 +1478,12 @@ type
         currparanr : byte;
         currparanr : byte;
         def_from,
         def_from,
         def_to   : tdef;
         def_to   : tdef;
+        currpt,
         pt       : tcallparanode;
         pt       : tcallparanode;
         eq       : tequaltype;
         eq       : tequaltype;
         convtype : tconverttype;
         convtype : tconverttype;
         pdoper   : tprocdef;
         pdoper   : tprocdef;
+        releasecurrpt : boolean;
       begin
       begin
         { process all procs }
         { process all procs }
         hp:=procs;
         hp:=procs;
@@ -1487,9 +1499,13 @@ type
            pt:=tcallparanode(left);
            pt:=tcallparanode(left);
            while assigned(pt) and assigned(currpara) do
            while assigned(pt) and assigned(currpara) do
             begin
             begin
+              { currpt can be changed from loadn to calln when a procvar
+                is passed. This is to prevent that the change is permanent }
+              currpt:=pt;
+              releasecurrpt:=false;
               { retrieve current parameter definitions to compares }
               { retrieve current parameter definitions to compares }
               eq:=te_incompatible;
               eq:=te_incompatible;
-              def_from:=pt.resulttype.def;
+              def_from:=currpt.resulttype.def;
               def_to:=currpara.paratype.def;
               def_to:=currpara.paratype.def;
               if not(assigned(def_from)) then
               if not(assigned(def_from)) then
                internalerror(200212091);
                internalerror(200212091);
@@ -1500,18 +1516,29 @@ type
                     ) then
                     ) then
                internalerror(200212092);
                internalerror(200212092);
 
 
+              { Convert tp procvars when not expecting a procvar }
+              if (def_to.deftype<>procvardef) and
+                 (currpt.left.resulttype.def.deftype=procvardef) then
+                begin
+                  releasecurrpt:=true;
+                  currpt:=tcallparanode(pt.getcopy);
+                  if maybe_call_procvar(currpt.left,true) then
+                    begin
+                      currpt.resulttype:=currpt.left.resulttype;
+                      def_from:=currpt.left.resulttype.def;
+                    end;
+                end;
+
               { varargs are always equal, but not exact }
               { varargs are always equal, but not exact }
               if (po_varargs in hp^.data.procoptions) and
               if (po_varargs in hp^.data.procoptions) and
                  (currparanr>hp^.data.minparacount) then
                  (currparanr>hp^.data.minparacount) then
                begin
                begin
-                 inc(hp^.equal_count);
                  eq:=te_equal;
                  eq:=te_equal;
                end
                end
               else
               else
               { same definition -> exact }
               { same definition -> exact }
                if (def_from=def_to) then
                if (def_from=def_to) then
                 begin
                 begin
-                  inc(hp^.exact_count);
                   eq:=te_exact;
                   eq:=te_exact;
                 end
                 end
               else
               else
@@ -1522,7 +1549,6 @@ type
                   is_integer(def_to) and
                   is_integer(def_to) and
                   is_in_limit(def_from,def_to) then
                   is_in_limit(def_from,def_to) then
                  begin
                  begin
-                   inc(hp^.equal_count);
                    eq:=te_equal;
                    eq:=te_equal;
                    hp^.ordinal_distance:=hp^.ordinal_distance+
                    hp^.ordinal_distance:=hp^.ordinal_distance+
                      abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
                      abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
@@ -1536,7 +1562,7 @@ type
               else
               else
               { generic type comparision }
               { generic type comparision }
                begin
                begin
-                 eq:=compare_defs_ext(def_from,def_to,pt.left.nodetype,convtype,pdoper,
+                 eq:=compare_defs_ext(def_from,def_to,currpt.left.nodetype,convtype,pdoper,
                                       [cdo_allow_variant,cdo_check_operator]);
                                       [cdo_allow_variant,cdo_check_operator]);
 
 
                  { when the types are not equal we need to check
                  { when the types are not equal we need to check
@@ -1550,32 +1576,39 @@ type
                         eq:=te_incompatible;
                         eq:=te_incompatible;
                         { var_para_allowed will return te_equal and te_convert_l1 to
                         { var_para_allowed will return te_equal and te_convert_l1 to
                           make a difference for best matching }
                           make a difference for best matching }
-                        var_para_allowed(eq,pt.resulttype.def,currpara.paratype.def)
+                        var_para_allowed(eq,currpt.resulttype.def,currpara.paratype.def)
                       end
                       end
                     else
                     else
-                      para_allowed(eq,pt,def_to);
+                      para_allowed(eq,currpt,def_to);
                   end;
                   end;
-
-                 case eq of
-                   te_exact :
-                     internalerror(200212071); { already checked }
-                   te_equal :
-                     inc(hp^.equal_count);
-                   te_convert_l1 :
-                     inc(hp^.cl1_count);
-                   te_convert_l2 :
-                     inc(hp^.cl2_count);
-                   te_convert_l3 :
-                     inc(hp^.cl3_count);
-                   te_convert_operator :
-                     inc(hp^.coper_count);
-                   te_incompatible :
-                     hp^.invalid:=true;
-                   else
-                     internalerror(200212072);
-                 end;
                end;
                end;
 
 
+              { when a procvar was changed to a call an exact much is
+                downgraded to equal. This way an overload call with the
+                procvar is choosen. See tb0471 (PFV) }
+              if (pt<>currpt) and (eq=te_exact) then
+                eq:=te_equal;
+
+              { increase correct counter }
+              case eq of
+                te_exact :
+                  inc(hp^.exact_count);
+                te_equal :
+                  inc(hp^.equal_count);
+                te_convert_l1 :
+                  inc(hp^.cl1_count);
+                te_convert_l2 :
+                  inc(hp^.cl2_count);
+                te_convert_l3 :
+                  inc(hp^.cl3_count);
+                te_convert_operator :
+                  inc(hp^.coper_count);
+                te_incompatible :
+                  hp^.invalid:=true;
+                else
+                  internalerror(200212072);
+              end;
+
               { stop checking when an incompatible parameter is found }
               { stop checking when an incompatible parameter is found }
               if hp^.invalid then
               if hp^.invalid then
                begin
                begin
@@ -1591,6 +1624,10 @@ type
               currpara.eqval:=eq;
               currpara.eqval:=eq;
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
 
 
+              { maybe release temp currpt }
+              if releasecurrpt then
+                currpt.free;
+
               { next parameter in the call tree }
               { next parameter in the call tree }
               pt:=tcallparanode(pt.right);
               pt:=tcallparanode(pt.right);
 
 
@@ -2719,7 +2756,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.226  2004-02-19 17:07:42  florian
+  Revision 1.227  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.226  2004/02/19 17:07:42  florian
     * fixed arg. area calculation
     * fixed arg. area calculation
 
 
   Revision 1.225  2004/02/13 15:42:21  peter
   Revision 1.225  2004/02/13 15:42:21  peter

+ 5 - 2
compiler/ncgcal.pas

@@ -88,7 +88,7 @@ implementation
 {$endif GDB}
 {$endif GDB}
       cgbase,pass_2,
       cgbase,pass_2,
       cpuinfo,aasmbase,aasmtai,
       cpuinfo,aasmbase,aasmtai,
-      nbas,nmem,nld,ncnv,
+      nbas,nmem,nld,ncnv,nutils,
 {$ifdef x86}
 {$ifdef x86}
       cga,cgx86,
       cga,cgx86,
 {$endif x86}
 {$endif x86}
@@ -1210,7 +1210,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.154  2004-02-11 19:59:06  peter
+  Revision 1.155  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.154  2004/02/11 19:59:06  peter
     * fix compilation without GDB
     * fix compilation without GDB
 
 
   Revision 1.153  2004/02/09 22:48:45  florian
   Revision 1.153  2004/02/09 22:48:45  florian

+ 5 - 2
compiler/ncgmem.pas

@@ -93,7 +93,7 @@ implementation
       symconst,symdef,symsym,defutil,paramgr,
       symconst,symdef,symsym,defutil,paramgr,
       aasmbase,aasmtai,
       aasmbase,aasmtai,
       procinfo,pass_2,
       procinfo,pass_2,
-      pass_1,nld,ncon,nadd,
+      pass_1,nld,ncon,nadd,nutils,
       cgobj,tgobj,ncgutil,symbase
       cgobj,tgobj,ncgutil,symbase
       ;
       ;
 
 
@@ -881,7 +881,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.86  2004-02-03 22:32:54  peter
+  Revision 1.87  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.86  2004/02/03 22:32:54  peter
     * renamed xNNbittype to xNNinttype
     * renamed xNNbittype to xNNinttype
     * renamed registers32 to registersint
     * renamed registers32 to registersint
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ

+ 11 - 39
compiler/ncnv.pas

@@ -202,7 +202,7 @@ implementation
       globtype,systems,tokens,
       globtype,systems,tokens,
       cutils,verbose,globals,widestr,
       cutils,verbose,globals,widestr,
       symconst,symdef,symsym,symtable,
       symconst,symdef,symsym,symtable,
-      ncon,ncal,nset,nadd,ninl,nmem,nmat,
+      ncon,ncal,nset,nadd,ninl,nmem,nmat,nutils,
       cgbase,procinfo,
       cgbase,procinfo,
       htypechk,pass_1,cpuinfo;
       htypechk,pass_1,cpuinfo;
 
 
@@ -1141,6 +1141,12 @@ implementation
             exit;
             exit;
           end;
           end;
 
 
+        { tp procvar support. Skip typecasts to record or set. Those
+          convert on the procvar value. This is used to access the
+          fields of a methodpointer }
+        if not(resulttype.def.deftype in [recorddef,setdef]) then
+          maybe_call_procvar(left,true);
+
         cdoptions:=[cdo_check_operator,cdo_allow_variant];
         cdoptions:=[cdo_check_operator,cdo_allow_variant];
         if nf_explicit in flags then
         if nf_explicit in flags then
           include(cdoptions,cdo_explicit);
           include(cdoptions,cdo_explicit);
@@ -1350,43 +1356,6 @@ implementation
         { Constant folding and other node transitions to
         { Constant folding and other node transitions to
           remove the typeconv node }
           remove the typeconv node }
         case left.nodetype of
         case left.nodetype of
-          loadn :
-            begin
-              { tp7 procvar support, when right is not a procvardef and we got a
-                loadn of a procvar (ignore procedures as void can not be converted)
-                then convert to a calln, the check for the result is already done
-                in is_convertible, also no conflict with @procvar is here because
-                that has an extra addrn.
-                The following deftypes always access the procvar: recorddef,setdef. This
-                has been tested with Kylix using trial and error }
-              if (m_tp_procvar in aktmodeswitches) and
-                 (resulttype.def.deftype<>procvardef) and
-                 { ignore internal typecasts to access methodpointer fields }
-                 not(resulttype.def.deftype in [recorddef,setdef]) and
-                 (left.resulttype.def.deftype=procvardef) and
-                 (not is_void(tprocvardef(left.resulttype.def).rettype.def)) then
-               begin
-                 hp:=ccallnode.create_procvar(nil,left);
-                 resulttypepass(hp);
-                 left:=hp;
-               end;
-            end;
-
-          calln :
-            begin
-              { See remark for loadn, this is the reverse }
-              if (m_tp_procvar in aktmodeswitches) and
-                 (resulttype.def.deftype in [recorddef,setdef]) and
-                 assigned(tcallnode(left).right) and
-                 (tcallnode(left).para_count=0) then
-               begin
-                 hp:=tcallnode(left).right.getcopy;
-                 resulttypepass(hp);
-                 left.free;
-                 left:=hp;
-               end;
-            end;
-
           niln :
           niln :
             begin
             begin
               { nil to ordinal node }
               { nil to ordinal node }
@@ -2410,7 +2379,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.139  2004-02-13 15:42:21  peter
+  Revision 1.140  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.139  2004/02/13 15:42:21  peter
     * compare_defs_ext has now a options argument
     * compare_defs_ext has now a options argument
     * fixes for variants
     * fixes for variants
 
 

+ 5 - 2
compiler/ninl.pas

@@ -74,7 +74,7 @@ implementation
       globtype, cutils,
       globtype, cutils,
       symbase,symconst,symdef,symsym,symtable,paramgr,defutil,defcmp,
       symbase,symconst,symdef,symsym,symtable,paramgr,defutil,defcmp,
       pass_1,
       pass_1,
-      ncal,ncon,ncnv,nadd,nld,nbas,nflw,nmem,nmat,
+      ncal,ncon,ncnv,nadd,nld,nbas,nflw,nmem,nmat,nutils,
       cgbase,procinfo
       cgbase,procinfo
       ;
       ;
 
 
@@ -2374,7 +2374,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.131  2004-02-04 18:45:29  jonas
+  Revision 1.132  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.131  2004/02/04 18:45:29  jonas
     + some more usage of register temps
     + some more usage of register temps
 
 
   Revision 1.130  2004/02/03 22:32:54  peter
   Revision 1.130  2004/02/03 22:32:54  peter

+ 11 - 142
compiler/nld.pas

@@ -133,14 +133,6 @@ interface
        crttinode : trttinodeclass;
        crttinode : trttinodeclass;
 
 
 
 
-    procedure load_procvar_from_calln(var p1:tnode);
-    function load_high_value_node(vs:tvarsym):tnode;
-    function load_self_node:tnode;
-    function load_result_node:tnode;
-    function load_self_pointer_node:tnode;
-    function load_vmt_pointer_node:tnode;
-    function is_self_node(p:tnode):boolean;
-
 
 
 implementation
 implementation
 
 
@@ -149,141 +141,10 @@ implementation
       symtable,symnot,
       symtable,symnot,
       defutil,defcmp,
       defutil,defcmp,
       htypechk,pass_1,procinfo,paramgr,
       htypechk,pass_1,procinfo,paramgr,
-      ncon,ninl,ncnv,nmem,ncal,cpubase,cgobj,cgbase
+      ncon,ninl,ncnv,nmem,ncal,nutils,
+      cpubase,cgobj,cgbase
       ;
       ;
 
 
-{*****************************************************************************
-                                 Helpers
-*****************************************************************************}
-
-      procedure load_procvar_from_calln(var p1:tnode);
-        var
-          p2 : tnode;
-        begin
-          if p1.nodetype<>calln then
-            internalerror(200212251);
-          { was it a procvar, then we simply remove the calln and
-            reuse the right }
-          if assigned(tcallnode(p1).right) then
-            begin
-              p2:=tcallnode(p1).right;
-              tcallnode(p1).right:=nil;
-            end
-          else
-            begin
-              p2:=cloadnode.create_procvar(tcallnode(p1).symtableprocentry,
-                 tprocdef(tcallnode(p1).procdefinition),tcallnode(p1).symtableproc);
-              { when the methodpointer is typen we've something like:
-                tobject.create. Then only the address is needed of the
-                method without a self pointer }
-              if assigned(tcallnode(p1).methodpointer) and
-                 (tcallnode(p1).methodpointer.nodetype<>typen) then
-               begin
-                 tloadnode(p2).set_mp(tcallnode(p1).methodpointer);
-                 tcallnode(p1).methodpointer:=nil;
-               end;
-            end;
-          resulttypepass(p2);
-          p1.free;
-          p1:=p2;
-        end;
-
-
-    function load_high_value_node(vs:tvarsym):tnode;
-      var
-        srsym : tsym;
-        srsymtable : tsymtable;
-      begin
-        result:=nil;
-        srsymtable:=vs.owner;
-        srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
-        if assigned(srsym) then
-          begin
-            result:=cloadnode.create(srsym,srsymtable);
-            resulttypepass(result);
-          end
-        else
-          CGMessage(cg_e_illegal_expression);
-      end;
-
-
-    function load_self_node:tnode;
-      var
-        srsym : tsym;
-        srsymtable : tsymtable;
-      begin
-        result:=nil;
-        searchsym('self',srsym,srsymtable);
-        if assigned(srsym) then
-          begin
-            result:=cloadnode.create(srsym,srsymtable);
-            resulttypepass(result);
-          end
-        else
-          CGMessage(cg_e_illegal_expression);
-      end;
-
-
-    function load_result_node:tnode;
-      var
-        srsym : tsym;
-        srsymtable : tsymtable;
-      begin
-        result:=nil;
-        searchsym('result',srsym,srsymtable);
-        if assigned(srsym) then
-          begin
-            result:=cloadnode.create(srsym,srsymtable);
-            resulttypepass(result);
-          end
-        else
-          CGMessage(cg_e_illegal_expression);
-      end;
-
-
-    function load_self_pointer_node:tnode;
-      var
-        srsym : tsym;
-        srsymtable : tsymtable;
-      begin
-        result:=nil;
-        searchsym('self',srsym,srsymtable);
-        if assigned(srsym) then
-          begin
-            result:=cloadnode.create(srsym,srsymtable);
-            include(result.flags,nf_load_self_pointer);
-            resulttypepass(result);
-          end
-        else
-          CGMessage(cg_e_illegal_expression);
-      end;
-
-
-    function load_vmt_pointer_node:tnode;
-      var
-        srsym : tsym;
-        srsymtable : tsymtable;
-      begin
-        result:=nil;
-        searchsym('vmt',srsym,srsymtable);
-        if assigned(srsym) then
-          begin
-            result:=cloadnode.create(srsym,srsymtable);
-            resulttypepass(result);
-          end
-        else
-          CGMessage(cg_e_illegal_expression);
-      end;
-
-
-    function is_self_node(p:tnode):boolean;
-      begin
-        is_self_node:=(p.nodetype=loadn) and
-                      (tloadnode(p).symtableentry.typ=varsym) and
-                      (vo_is_self in tvarsym(tloadnode(p).symtableentry).varoptions);
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                              TLOADNODE
                              TLOADNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -656,6 +517,11 @@ implementation
         if codegenerror then
         if codegenerror then
           exit;
           exit;
 
 
+        { tp procvar support, when we don't expect a procvar
+          then we need to call the procvar }
+        if (left.resulttype.def.deftype<>procvardef) then
+          maybe_call_procvar(right,true);
+
         { assignments to formaldefs and open arrays aren't allowed }
         { assignments to formaldefs and open arrays aren't allowed }
         if (left.resulttype.def.deftype=formaldef) or
         if (left.resulttype.def.deftype=formaldef) or
            is_open_array(left.resulttype.def) then
            is_open_array(left.resulttype.def) then
@@ -1256,7 +1122,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.122  2004-02-20 20:21:16  daniel
+  Revision 1.123  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.122  2004/02/20 20:21:16  daniel
     * Tarrayconstructornode sets pi_do_call if a call is possible
     * Tarrayconstructornode sets pi_do_call if a call is possible
 
 
   Revision 1.121  2004/02/03 22:32:54  peter
   Revision 1.121  2004/02/03 22:32:54  peter

+ 10 - 2
compiler/nmem.pas

@@ -130,7 +130,7 @@ implementation
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,symbase,defutil,defcmp,
       symconst,symbase,defutil,defcmp,
-      nbas,
+      nbas,nutils,
       htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase,procinfo
       htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase,procinfo
       ;
       ;
 
 
@@ -516,6 +516,9 @@ implementation
          if codegenerror then
          if codegenerror then
           exit;
           exit;
 
 
+         { tp procvar support }
+         maybe_call_procvar(left,true);
+
          if left.resulttype.def.deftype=pointerdef then
          if left.resulttype.def.deftype=pointerdef then
           resulttype:=tpointerdef(left.resulttype.def).pointertype
           resulttype:=tpointerdef(left.resulttype.def).pointertype
          else
          else
@@ -601,6 +604,8 @@ implementation
       begin
       begin
         result:=nil;
         result:=nil;
         resulttypepass(left);
         resulttypepass(left);
+        { tp procvar support }
+        maybe_call_procvar(left,true);
         resulttype:=vs.vartype;
         resulttype:=vs.vartype;
       end;
       end;
 
 
@@ -970,7 +975,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.79  2004-02-03 22:32:54  peter
+  Revision 1.80  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.79  2004/02/03 22:32:54  peter
     * renamed xNNbittype to xNNinttype
     * renamed xNNbittype to xNNinttype
     * renamed registers32 to registersint
     * renamed registers32 to registersint
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ

+ 177 - 4
compiler/nutils.pas

@@ -27,7 +27,7 @@ unit nutils;
 interface
 interface
 
 
   uses
   uses
-    node;
+    symsym,node;
 
 
   type
   type
     { resulttype of functions that process on all nodes in a (sub)tree }
     { resulttype of functions that process on all nodes in a (sub)tree }
@@ -50,6 +50,15 @@ interface
     function foreachnode(var n: tnode; f: foreachnodefunction): boolean;
     function foreachnode(var n: tnode; f: foreachnodefunction): boolean;
     function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean;
     function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean;
 
 
+    procedure load_procvar_from_calln(var p1:tnode);
+    function maybe_call_procvar(var p1:tnode;tponly:boolean):boolean;
+    function load_high_value_node(vs:tvarsym):tnode;
+    function load_self_node:tnode;
+    function load_result_node:tnode;
+    function load_self_pointer_node:tnode;
+    function load_vmt_pointer_node:tnode;
+    function is_self_node(p:tnode):boolean;
+
     function call_fail_node:tnode;
     function call_fail_node:tnode;
     function initialize_data_node(p:tnode):tnode;
     function initialize_data_node(p:tnode):tnode;
     function finalize_data_node(p:tnode):tnode;
     function finalize_data_node(p:tnode):tnode;
@@ -58,8 +67,8 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      verbose,
-      symconst,symsym,symtype,symdef,symtable,
+      globtype,globals,verbose,
+      symconst,symbase,symtype,symdef,symtable,
       nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,
       nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,
       cgbase,procinfo,
       cgbase,procinfo,
       pass_1;
       pass_1;
@@ -157,6 +166,167 @@ implementation
     end;
     end;
 
 
 
 
+    procedure load_procvar_from_calln(var p1:tnode);
+      var
+        p2 : tnode;
+      begin
+        if p1.nodetype<>calln then
+          internalerror(200212251);
+        { was it a procvar, then we simply remove the calln and
+          reuse the right }
+        if assigned(tcallnode(p1).right) then
+          begin
+            p2:=tcallnode(p1).right;
+            tcallnode(p1).right:=nil;
+          end
+        else
+          begin
+            p2:=cloadnode.create_procvar(tcallnode(p1).symtableprocentry,
+               tprocdef(tcallnode(p1).procdefinition),tcallnode(p1).symtableproc);
+            { when the methodpointer is typen we've something like:
+              tobject.create. Then only the address is needed of the
+              method without a self pointer }
+            if assigned(tcallnode(p1).methodpointer) and
+               (tcallnode(p1).methodpointer.nodetype<>typen) then
+             begin
+               tloadnode(p2).set_mp(tcallnode(p1).methodpointer);
+               tcallnode(p1).methodpointer:=nil;
+             end;
+          end;
+        resulttypepass(p2);
+        p1.free;
+        p1:=p2;
+      end;
+
+
+    function maybe_call_procvar(var p1:tnode;tponly:boolean):boolean;
+      var
+        hp : tnode;
+      begin
+        result:=false;
+        if (p1.resulttype.def.deftype<>procvardef) or
+           (tponly and
+            not(m_tp_procvar in aktmodeswitches)) then
+          exit;
+        { ignore vecn,subscriptn }
+        hp:=p1;
+        repeat
+          case hp.nodetype of
+            vecn,
+            derefn,
+            typeconvn,
+            subscriptn :
+              hp:=tunarynode(hp).left;
+            else
+              break;
+          end;
+        until false;
+        if (hp.nodetype=loadn) then
+          begin
+            hp:=ccallnode.create_procvar(nil,p1);
+            resulttypepass(hp);
+            p1:=hp;
+            result:=true;
+          end;
+      end;
+
+
+    function load_high_value_node(vs:tvarsym):tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        srsymtable:=vs.owner;
+        srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_self_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('self',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_result_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('result',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_self_pointer_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('self',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            include(result.flags,nf_load_self_pointer);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_vmt_pointer_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('vmt',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function is_self_node(p:tnode):boolean;
+      begin
+        is_self_node:=(p.nodetype=loadn) and
+                      (tloadnode(p).symtableentry.typ=varsym) and
+                      (vo_is_self in tvarsym(tloadnode(p).symtableentry).varoptions);
+      end;
+
+
+
     function call_fail_node:tnode;
     function call_fail_node:tnode;
       var
       var
         para : tcallparanode;
         para : tcallparanode;
@@ -254,7 +424,10 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2004-02-03 22:32:54  peter
+  Revision 1.10  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.9  2004/02/03 22:32:54  peter
     * renamed xNNbittype to xNNinttype
     * renamed xNNbittype to xNNinttype
     * renamed registers32 to registersint
     * renamed registers32 to registersint
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ

+ 6 - 6
compiler/pdecvar.pas

@@ -48,7 +48,7 @@ implementation
        fmodule,
        fmodule,
        { pass 1 }
        { pass 1 }
        node,pass_1,
        node,pass_1,
-       nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,nmem,
+       nmat,nadd,ncal,nset,ncnv,ninl,ncon,nld,nflw,nmem,nutils,
        { codegen }
        { codegen }
        ncgutil,
        ncgutil,
        { parser }
        { parser }
@@ -725,9 +725,6 @@ implementation
                   Message(parser_e_absolute_only_one_var);
                   Message(parser_e_absolute_only_one_var);
                 { parse the rest }
                 { parse the rest }
                 pt:=expr;
                 pt:=expr;
-                { transform a procvar calln to loadn }
-                if pt.nodetype=calln then
-                  load_procvar_from_calln(pt);
                 { check allowed absolute types }
                 { check allowed absolute types }
                 if (pt.nodetype=stringconstn) or
                 if (pt.nodetype=stringconstn) or
                    (is_constcharnode(pt)) then
                    (is_constcharnode(pt)) then
@@ -1117,7 +1114,7 @@ implementation
               { Align the offset where the union symtable is added }
               { Align the offset where the union symtable is added }
               if (trecordsymtable(symtablestack).usefieldalignment=-1) then
               if (trecordsymtable(symtablestack).usefieldalignment=-1) then
                 usedalign:=used_align(maxalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
                 usedalign:=used_align(maxalignment,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
-              else  
+              else
                 usedalign:=used_align(maxalignment,aktalignment.recordalignmin,aktalignment.recordalignmax);
                 usedalign:=used_align(maxalignment,aktalignment.recordalignmin,aktalignment.recordalignmax);
               offset:=align(trecordsymtable(symtablestack).datasize,usedalign);
               offset:=align(trecordsymtable(symtablestack).datasize,usedalign);
               trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
               trecordsymtable(symtablestack).datasize:=offset+unionsymtable.datasize;
@@ -1138,7 +1135,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.66  2004-02-17 15:57:49  peter
+  Revision 1.67  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.66  2004/02/17 15:57:49  peter
   - fix rtti generation for properties containing sl_vec
   - fix rtti generation for properties containing sl_vec
   - fix crash when overloaded operator is not available
   - fix crash when overloaded operator is not available
   - fix record alignment for C style variant records
   - fix record alignment for C style variant records

+ 25 - 92
compiler/pexpr.pas

@@ -75,7 +75,7 @@ implementation
        symconst,symtable,symsym,defutil,defcmp,
        symconst,symtable,symsym,defutil,defcmp,
        { pass 1 }
        { pass 1 }
        pass_1,htypechk,
        pass_1,htypechk,
-       nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,
+       nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
        { parser }
        { parser }
        scanner,
        scanner,
        pbase,pinline,
        pbase,pinline,
@@ -286,50 +286,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure check_tp_procvar(var p : tnode);
-      var
-         hp,
-         p1 : tnode;
-      begin
-         if (m_tp_procvar in aktmodeswitches) and
-            (token<>_ASSIGNMENT) and
-            (not got_addrn) and
-            (block_type=bt_body) then
-          begin
-            { ignore vecn,subscriptn }
-            hp:=p;
-            repeat
-              case hp.nodetype of
-                vecn :
-                  hp:=tvecnode(hp).left;
-                subscriptn :
-                  hp:=tsubscriptnode(hp).left;
-                else
-                  break;
-              end;
-            until false;
-            if (hp.nodetype=loadn) then
-               begin
-                  { get the resulttype of p }
-                  do_resulttypepass(p);
-                  { convert the procvar load to a call:
-                     - not expecting a procvar
-                     - the procvar does not get arguments, when it
-                       requires arguments the callnode will fail
-                       Note: When arguments were passed there was no loadn }
-                  if (getprocvardef=nil) and
-                     (p.resulttype.def.deftype=procvardef) and
-                     (tprocvardef(p.resulttype.def).minparacount=0) then
-                    begin
-                       p1:=ccallnode.create_procvar(nil,p);
-                       resulttypepass(p1);
-                       p:=p1;
-                    end;
-               end;
-          end;
-      end;
-
-
      function statement_syssym(l : longint) : tnode;
      function statement_syssym(l : longint) : tnode;
       var
       var
         p1,p2,paras  : tnode;
         p1,p2,paras  : tnode;
@@ -471,16 +427,6 @@ implementation
               p1:=comp_expr(true);
               p1:=comp_expr(true);
               if not codegenerror then
               if not codegenerror then
                begin
                begin
-                 { With tp procvars we allways need to load a
-                   procvar when it is passed, but not when the
-                   callnode is inserted due a property or has
-                   arguments }
-                 if (m_tp_procvar in aktmodeswitches) and
-                    (p1.nodetype=calln) and
-                    (tcallnode(p1).para_count=0) and
-                    not(nf_isproperty in tcallnode(p1).flags) then
-                   load_procvar_from_calln(p1);
-
                  case p1.resulttype.def.deftype of
                  case p1.resulttype.def.deftype of
                    procdef, { procvar }
                    procdef, { procvar }
                    pointerdef,
                    pointerdef,
@@ -1761,31 +1707,22 @@ implementation
 
 
                else
                else
                  begin
                  begin
-                 { is this a procedure variable ? }
-                   if assigned(p1.resulttype.def) then
-                    begin
-                      if (p1.resulttype.def.deftype=procvardef) then
-                       begin
-                         if assigned(getprocvardef) and
-                            equal_defs(p1.resulttype.def,getprocvardef) then
-                           again:=false
-                         else
-                           if (token=_LKLAMMER) or
-                              ((tprocvardef(p1.resulttype.def).maxparacount=0) and
-                               (not((token in [_ASSIGNMENT,_UNEQUAL,_EQUAL]))) and
-                               (not afterassignment) and
-                               (not in_args)) then
+                   { is this a procedure variable ? }
+                   if assigned(p1.resulttype.def) and
+                      (p1.resulttype.def.deftype=procvardef) then
+                     begin
+                       if assigned(getprocvardef) and
+                          equal_defs(p1.resulttype.def,getprocvardef) then
+                         again:=false
+                       else
+                         begin
+                           if try_to_consume(_LKLAMMER) then
                              begin
                              begin
-                                if try_to_consume(_LKLAMMER) then
-                                  begin
-                                     p2:=parse_paras(false,false);
-                                     consume(_RKLAMMER);
-                                  end
-                                else
-                                  p2:=nil;
-                                p1:=ccallnode.create_procvar(p2,p1);
-                                { proc():= is never possible }
-                                if token=_ASSIGNMENT then
+                               p2:=parse_paras(false,false);
+                               consume(_RKLAMMER);
+                               p1:=ccallnode.create_procvar(p2,p1);
+                               { proc():= is never possible }
+                               if token=_ASSIGNMENT then
                                  begin
                                  begin
                                    Message(cg_e_illegal_expression);
                                    Message(cg_e_illegal_expression);
                                    p1.free;
                                    p1.free;
@@ -1793,14 +1730,12 @@ implementation
                                    again:=false;
                                    again:=false;
                                  end;
                                  end;
                              end
                              end
-                         else
-                           again:=false;
-                       end
-                      else
-                       again:=false;
-                    end
+                           else
+                             again:=false;
+                         end;
+                     end
                    else
                    else
-                    again:=false;
+                     again:=false;
                   end;
                   end;
              end;
              end;
            end; { while again }
            end; { while again }
@@ -2248,10 +2183,6 @@ implementation
         if (not assigned(p1.resulttype.def)) then
         if (not assigned(p1.resulttype.def)) then
          do_resulttypepass(p1);
          do_resulttypepass(p1);
 
 
-        { tp7 procvar handling, but not if the next token
-          will be a := }
-        check_tp_procvar(p1);
-
         factor:=p1;
         factor:=p1;
         check_tokenpos;
         check_tokenpos;
       end;
       end;
@@ -2387,7 +2318,6 @@ implementation
          if not assigned(p1.resulttype.def) then
          if not assigned(p1.resulttype.def) then
           do_resulttypepass(p1);
           do_resulttypepass(p1);
          filepos:=akttokenpos;
          filepos:=akttokenpos;
-         check_tp_procvar(p1);
          if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
          if token in [_ASSIGNMENT,_PLUSASN,_MINUSASN,_STARASN,_SLASHASN] then
            afterassignment:=true;
            afterassignment:=true;
          oldp1:=p1;
          oldp1:=p1;
@@ -2489,7 +2419,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.149  2004-02-18 21:58:53  peter
+  Revision 1.150  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.149  2004/02/18 21:58:53  peter
     * constants are now parsed as 64bit for cpu64bit
     * constants are now parsed as 64bit for cpu64bit
 
 
   Revision 1.148  2004/02/17 23:36:40  daniel
   Revision 1.148  2004/02/17 23:36:40  daniel

+ 20 - 11
compiler/pstatmnt.pas

@@ -941,16 +941,22 @@ implementation
               end;
               end;
 
 
              if p.nodetype=labeln then
              if p.nodetype=labeln then
-              begin
-                { the pointer to the following instruction }
-                { isn't a very clean way                   }
-                if token in endtokens then
-                  tlabelnode(p).left:=cnothingnode.create
-                else
-                  tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
-                { be sure to have left also resulttypepass }
-                resulttypepass(tlabelnode(p).left);
-              end;
+               begin
+                 { the pointer to the following instruction }
+                 { isn't a very clean way                   }
+                 if token in endtokens then
+                   tlabelnode(p).left:=cnothingnode.create
+                 else
+                   tlabelnode(p).left:=statement{$ifdef FPCPROCVAR}(){$endif};
+                 { be sure to have left also resulttypepass }
+                 resulttypepass(tlabelnode(p).left);
+               end
+             else
+               begin
+                 { change a load of a procvar to a call. this is also
+                   supported in fpc mode }
+                 maybe_call_procvar(p,false);
+               end;
 
 
              { blockn support because a read/write is changed into a blocknode }
              { blockn support because a read/write is changed into a blocknode }
              { with a separate statement for each read/write operation (JM)    }
              { with a separate statement for each read/write operation (JM)    }
@@ -1092,7 +1098,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.129  2004-02-03 22:32:54  peter
+  Revision 1.130  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.129  2004/02/03 22:32:54  peter
     * renamed xNNbittype to xNNinttype
     * renamed xNNbittype to xNNinttype
     * renamed registers32 to registersint
     * renamed registers32 to registersint
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ
     * replace some s32bit,u32bit with torddef([su]inttype).def.typ

+ 8 - 5
compiler/symtable.pas

@@ -765,7 +765,7 @@ implementation
               [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
               [objectsymtable,parasymtable,localsymtable,staticsymtable])) then
           begin
           begin
            if (Errorcount<>0) or
            if (Errorcount<>0) or
-              (copy(p.name,1,3)='def') then
+              (sp_internal in tsym(p).symoptions) then
              exit;
              exit;
            { do not claim for inherited private fields !! }
            { do not claim for inherited private fields !! }
            if (Tsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
            if (Tsym(p).refs=0) and (tsym(p).owner.symtabletype=objectsymtable) then
@@ -1090,7 +1090,7 @@ implementation
         { Calc alignment needed for this record }
         { Calc alignment needed for this record }
         if (usefieldalignment=-1) then
         if (usefieldalignment=-1) then
           varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
           varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.maxCrecordalign)
-        else  
+        else
           varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.recordalignmax);
           varalignrecord:=used_align(varalign,aktalignment.recordalignmin,aktalignment.recordalignmax);
         recordalignment:=max(recordalignment,varalignrecord);
         recordalignment:=max(recordalignment,varalignrecord);
       end;
       end;
@@ -1847,10 +1847,10 @@ implementation
                    end;
                    end;
                  if (not assigned(topclass)) or
                  if (not assigned(topclass)) or
                     Tsym(srsym).is_visible_for_object(topclass) then
                     Tsym(srsym).is_visible_for_object(topclass) then
-                   begin 
+                   begin
                      searchsym:=true;
                      searchsym:=true;
                      exit;
                      exit;
-                   end;  
+                   end;
                end;
                end;
              srsymtable:=srsymtable.next;
              srsymtable:=srsymtable.next;
            end;
            end;
@@ -2427,7 +2427,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.138  2004-02-17 15:57:49  peter
+  Revision 1.139  2004-02-20 21:55:59  peter
+    * procvar cleanup
+
+  Revision 1.138  2004/02/17 15:57:49  peter
   - fix rtti generation for properties containing sl_vec
   - fix rtti generation for properties containing sl_vec
   - fix crash when overloaded operator is not available
   - fix crash when overloaded operator is not available
   - fix record alignment for C style variant records
   - fix record alignment for C style variant records