Browse Source

* removed newn and disposen nodes, the code is now directly
inlined from pexpr
* -an option that will write the secondpass nodes to the .s file, this
requires EXTDEBUG define to actually write the info
* fixed various internal errors and crashes due recent code changes

peter 23 years ago
parent
commit
6320530bdd

+ 9 - 2
compiler/globtype.pas

@@ -122,7 +122,7 @@ interface
          cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
          cs_gdb_dbx,cs_gdb_gsym,cs_gdb_heaptrc,cs_gdb_lineinfo,cs_checkpointer,
          { assembling }
          { assembling }
          cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
          cs_asm_leave,cs_asm_extern,cs_asm_pipe,cs_asm_source,
-         cs_asm_regalloc,cs_asm_tempalloc,
+         cs_asm_regalloc,cs_asm_tempalloc,cs_asm_nodes,
          { linking }
          { linking }
          cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
          cs_link_extern,cs_link_static,cs_link_smart,cs_link_shared,cs_link_deffile,
          cs_link_strip,cs_link_staticflag,cs_link_on_target
          cs_link_strip,cs_link_staticflag,cs_link_on_target
@@ -253,7 +253,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.21  2002-03-24 19:05:59  carl
+  Revision 1.22  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.21  2002/03/24 19:05:59  carl
   + patch for SPARC from Mazen NEIFER
   + patch for SPARC from Mazen NEIFER
 
 
   Revision 1.20  2002/01/24 18:25:48  peter
   Revision 1.20  2002/01/24 18:25:48  peter

+ 14 - 2
compiler/i386/n386cal.pas

@@ -63,7 +63,7 @@ implementation
       cginfo,cgbase,pass_2,
       cginfo,cgbase,pass_2,
       cpubase,
       cpubase,
       nmem,nld,ncnv,
       nmem,nld,ncnv,
-      tainst,cga,cgobj,tgobj,n386ld,n386util,regvars,rgobj,rgcpu,cg64f32,cgcpu;
+      tainst,cga,cgobj,tgobj,n386ld,n386util,ncgutil,regvars,rgobj,rgcpu,cg64f32,cgcpu;
 
 
 {*****************************************************************************
 {*****************************************************************************
                              TI386CALLPARANODE
                              TI386CALLPARANODE
@@ -133,6 +133,11 @@ implementation
          else if assigned(defcoll.paratype.def) and
          else if assigned(defcoll.paratype.def) and
                  (defcoll.paratype.def.deftype=formaldef) then
                  (defcoll.paratype.def.deftype=formaldef) then
            begin
            begin
+              { allow passing of a constant to a const formaldef }
+              if (defcoll.paratyp=vs_const) and
+                 (left.location.loc=LOC_CONSTANT) then
+                location_force_mem(left.location);
+
               { allow @var }
               { allow @var }
               inc(pushedparasize,4);
               inc(pushedparasize,4);
               if (left.nodetype=addrn) and
               if (left.nodetype=addrn) and
@@ -1477,7 +1482,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.46  2002-04-21 15:34:25  carl
+  Revision 1.47  2002-04-21 19:02:07  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.46  2002/04/21 15:34:25  carl
   * changeregsize -> rg.makeregsize
   * changeregsize -> rg.makeregsize
 
 
   Revision 1.45  2002/04/15 19:44:21  peter
   Revision 1.45  2002/04/15 19:44:21  peter

+ 17 - 2
compiler/i386/n386cnv.pas

@@ -249,7 +249,15 @@ implementation
               end;
               end;
             LOC_REGISTER,LOC_CREGISTER :
             LOC_REGISTER,LOC_CREGISTER :
               begin
               begin
-                cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
+                if left.location.size in [OS_64,OS_S64] then
+                 begin
+                   hregister:=cg.get_scratch_reg(exprasmlist);
+                   cg.a_load_reg_reg(exprasmlist,OS_32,left.location.registerlow,hregister);
+                   cg.a_op_reg_reg(exprasmlist,OP_OR,OS_32,left.location.registerhigh,hregister);
+                   cg.free_scratch_reg(exprasmlist,hregister);
+                 end
+                else
+                 cg.a_op_reg_reg(exprasmlist,OP_OR,left.location.size,left.location.register,left.location.register);
               end;
               end;
             LOC_JUMP :
             LOC_JUMP :
               begin
               begin
@@ -364,7 +372,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.36  2002-04-21 15:35:23  carl
+  Revision 1.37  2002-04-21 19:02:07  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.36  2002/04/21 15:35:23  carl
   * changeregsize -> rg.makeregsize
   * changeregsize -> rg.makeregsize
 
 
   Revision 1.35  2002/04/19 15:39:35  peter
   Revision 1.35  2002/04/19 15:39:35  peter

+ 13 - 144
compiler/i386/n386mem.pas

@@ -30,18 +30,10 @@ interface
       node,nmem,ncgmem;
       node,nmem,ncgmem;
 
 
     type
     type
-       ti386newnode = class(tnewnode)
-          procedure pass_2;override;
-       end;
-
        ti386addrnode = class(tcgaddrnode)
        ti386addrnode = class(tcgaddrnode)
           procedure pass_2;override;
           procedure pass_2;override;
        end;
        end;
 
 
-       ti386simplenewdisposenode = class(tsimplenewdisposenode)
-          procedure pass_2;override;
-       end;
-
        ti386derefnode = class(tcgderefnode)
        ti386derefnode = class(tcgderefnode)
           procedure pass_2;override;
           procedure pass_2;override;
        end;
        end;
@@ -64,54 +56,6 @@ implementation
       cpuinfo,cpubase,
       cpuinfo,cpubase,
       cgobj,cga,tgobj,rgobj,ncgutil,n386util;
       cgobj,cga,tgobj,rgobj,ncgutil,n386util;
 
 
-{*****************************************************************************
-                            TI386NEWNODE
-*****************************************************************************}
-
-    procedure ti386newnode.pass_2;
-      var
-         pushed : tpushedsaved;
-         regstopush: tregisterset;
-         href : treference;
-      begin
-         if assigned(left) then
-           begin
-              secondpass(left);
-              location_copy(location,left.location);
-           end
-         else
-           begin
-              location_reset(location,LOC_REFERENCE,OS_ADDR);
-
-              regstopush := all_registers;
-              remove_non_regvars_from_loc(location,regstopush);
-              rg.saveusedregisters(exprasmlist,pushed,regstopush);
-
-              tg.gettempofsizereference(exprasmlist,pointer_size,location.reference);
-
-              { determines the size of the mem block }
-              push_int(tpointerdef(resulttype.def).pointertype.def.size);
-              emit_push_lea_loc(location,false);
-              rg.saveregvars(exprasmlist,all_registers);
-              emitcall('FPC_GETMEM');
-
-              if tpointerdef(resulttype.def).pointertype.def.needs_inittable then
-                begin
-                   reference_reset_symbol(href,tstoreddef(tpointerdef(resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
-                   emitpushreferenceaddr(href);
-
-                   { push pointer we just allocated, we need to initialize the
-                     data located at that pointer not the pointer self (PFV) }
-                   cg.a_param_loc(exprasmlist,location,1);
-                   emitcall('FPC_INITIALIZE');
-                end;
-              rg.restoreusedregisters(exprasmlist,pushed);
-              { may be load ESI }
-              maybe_loadself;
-           end;
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                              TI386ADDRNODE
                              TI386ADDRNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -125,86 +69,6 @@ implementation
           location.segment:=left.location.reference.segment;
           location.segment:=left.location.reference.segment;
       end;
       end;
 
 
-{*****************************************************************************
-                         TI386SIMPLENEWDISPOSENODE
-*****************************************************************************}
-
-    procedure ti386simplenewdisposenode.pass_2;
-
-      var
-         regstopush: tregisterset;
-         pushed : tpushedsaved;
-         href : treference;
-         lefttemp: treference;
-         left_needs_initfinal: boolean;
-
-         procedure saveleft;
-         begin
-           tg.gettempofsizereference(exprasmlist,pointer_size,lefttemp);
-           cg.a_load_loc_ref(exprasmlist,left.location,lefttemp);
-           location_release(exprasmlist,left.location);
-         end;
-
-      begin
-         secondpass(left);
-         if codegenerror then
-           exit;
-
-         left_needs_initfinal:=tpointerdef(left.resulttype.def).pointertype.def.needs_inittable;
-
-         regstopush := all_registers;
-         remove_non_regvars_from_loc(left.location,regstopush);
-         rg.saveusedregisters(exprasmlist,pushed,regstopush);
-         rg.saveregvars(exprasmlist,all_registers);
-
-         { call the mem handling procedures }
-         case nodetype of
-           simpledisposen:
-             begin
-                if left_needs_initfinal then
-                  begin
-                     reference_reset_symbol(href,tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
-                     emitpushreferenceaddr(href);
-                     { push pointer adress }
-                     cg.a_param_loc(exprasmlist,left.location,1);
-                     { save left and free its registers }
-                     saveleft;
-                     emitcall('FPC_FINALIZE');
-                     { push left again as parameter for freemem }
-                     emit_push_mem(lefttemp);
-                     tg.ungetiftemp(exprasmlist,lefttemp);
-                  end
-                else
-                  begin
-                    cg.a_param_loc(exprasmlist,left.location,1);
-                    location_release(exprasmlist,left.location);
-                  end;
-                emitcall('FPC_FREEMEM');
-             end;
-           simplenewn:
-             begin
-                { determines the size of the mem block }
-                push_int(tpointerdef(left.resulttype.def).pointertype.def.size);
-                emit_push_lea_loc(left.location,true);
-                { save left and free its registers }
-                if left_needs_initfinal then
-                  saveleft;
-                emitcall('FPC_GETMEM');
-                if left_needs_initfinal then
-                  begin
-                     reference_reset_symbol(href,tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti),0);
-                     emitpushreferenceaddr(href);
-                     emit_push_mem(lefttemp);
-                     tg.ungetiftemp(exprasmlist,lefttemp);
-                     emitcall('FPC_INITIALIZE');
-                  end;
-             end;
-         end;
-         rg.restoreusedregisters(exprasmlist,pushed);
-         { may be load ESI }
-         maybe_loadself;
-      end;
-
 
 
 {*****************************************************************************
 {*****************************************************************************
                            TI386DEREFNODE
                            TI386DEREFNODE
@@ -219,11 +83,11 @@ implementation
          if not tpointerdef(left.resulttype.def).is_far and
          if not tpointerdef(left.resulttype.def).is_far and
             (cs_gdb_heaptrc in aktglobalswitches) and
             (cs_gdb_heaptrc in aktglobalswitches) and
             (cs_checkpointer in aktglobalswitches) then
             (cs_checkpointer in aktglobalswitches) then
-              begin
-                 emit_reg(
-                   A_PUSH,S_L,location.reference.base);
-                 emitcall('FPC_CHECKPOINTER');
-              end;
+          begin
+             emit_reg(
+               A_PUSH,S_L,location.reference.base);
+             emitcall('FPC_CHECKPOINTER');
+          end;
       end;
       end;
 
 
 
 
@@ -655,15 +519,20 @@ implementation
 
 
 
 
 begin
 begin
-   cnewnode:=ti386newnode;
-   csimplenewdisposenode:=ti386simplenewdisposenode;
    caddrnode:=ti386addrnode;
    caddrnode:=ti386addrnode;
    cderefnode:=ti386derefnode;
    cderefnode:=ti386derefnode;
    cvecnode:=ti386vecnode;
    cvecnode:=ti386vecnode;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.27  2002-04-20 21:37:07  carl
+  Revision 1.28  2002-04-21 19:02:07  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.27  2002/04/20 21:37:07  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 15 - 2
compiler/i386/n386set.pas

@@ -899,7 +899,13 @@ implementation
          opsize:=bytes2Sxx[left.resulttype.def.size];
          opsize:=bytes2Sxx[left.resulttype.def.size];
          { copy the case expression to a register }
          { copy the case expression to a register }
          location_force_reg(left.location,def_cgsize(left.resulttype.def),false);
          location_force_reg(left.location,def_cgsize(left.resulttype.def),false);
-         hregister:=left.location.register;
+         if opsize=S_Q then
+          begin
+            hregister:=left.location.registerlow;
+            hregister2:=left.location.registerhigh;
+          end
+         else
+          hregister:=left.location.register;
          if isjump then
          if isjump then
           begin
           begin
             truelabel:=otl;
             truelabel:=otl;
@@ -1030,7 +1036,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.24  2002-04-21 15:37:26  carl
+  Revision 1.25  2002-04-21 19:02:07  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.24  2002/04/21 15:37:26  carl
   * changeregsize -> rg.makeregsize
   * changeregsize -> rg.makeregsize
 
 
   Revision 1.23  2002/04/19 15:39:35  peter
   Revision 1.23  2002/04/19 15:39:35  peter

+ 58 - 6
compiler/nbas.pas

@@ -81,7 +81,6 @@ interface
          { refs and deletenode can hook to this copy once they get copied too    }
          { refs and deletenode can hook to this copy once they get copied too    }
          hookoncopy : ptempinfo;
          hookoncopy : ptempinfo;
          ref        : treference;
          ref        : treference;
-         size       : longint;
          restype    : ttype;
          restype    : ttype;
          valid      : boolean;
          valid      : boolean;
        end;
        end;
@@ -91,6 +90,7 @@ interface
        ttempcreatenode = class(tnode)
        ttempcreatenode = class(tnode)
           size: longint;
           size: longint;
           tempinfo: ptempinfo;
           tempinfo: ptempinfo;
+          persistent: boolean;
           { * persistent temps are used in manually written code where the temp }
           { * persistent temps are used in manually written code where the temp }
           { be usable among different statements and where you can manually say }
           { be usable among different statements and where you can manually say }
           { when the temp has to be freed (using a ttempdeletenode)             }
           { when the temp has to be freed (using a ttempdeletenode)             }
@@ -103,8 +103,6 @@ interface
           function pass_1 : tnode; override;
           function pass_1 : tnode; override;
           function det_resulttype: tnode; override;
           function det_resulttype: tnode; override;
           function docompare(p: tnode): boolean; override;
           function docompare(p: tnode): boolean; override;
-         protected
-          persistent: boolean;
         end;
         end;
        ttempcreatenodeclass = class of ttempcreatenode;
        ttempcreatenodeclass = class of ttempcreatenode;
 
 
@@ -123,6 +121,9 @@ interface
         { a node which removes a temp }
         { a node which removes a temp }
         ttempdeletenode = class(tnode)
         ttempdeletenode = class(tnode)
           constructor create(const temp: ttempcreatenode);
           constructor create(const temp: ttempcreatenode);
+          { this will convert the persistant temp to a normal temp
+            for returning to the other nodes }
+          constructor create_normal_temp(const temp: ttempcreatenode);
           function getcopy: tnode; override;
           function getcopy: tnode; override;
           function pass_1: tnode; override;
           function pass_1: tnode; override;
           function det_resulttype: tnode; override;
           function det_resulttype: tnode; override;
@@ -130,6 +131,7 @@ interface
           destructor destroy; override;
           destructor destroy; override;
          protected
          protected
           tempinfo: ptempinfo;
           tempinfo: ptempinfo;
+          release_to_normal : boolean;
         end;
         end;
        ttempdeletenodeclass = class of ttempdeletenode;
        ttempdeletenodeclass = class of ttempdeletenode;
 
 
@@ -143,6 +145,12 @@ interface
        ctemprefnode : ttemprefnodeclass;
        ctemprefnode : ttemprefnodeclass;
        ctempdeletenode : ttempdeletenodeclass;
        ctempdeletenode : ttempdeletenodeclass;
 
 
+       { Create a blocknode and statement node for multiple statements
+         generated internally by the parser }
+       function  internalstatements(var laststatement:tstatementnode):tblocknode;
+       procedure addstatement(var laststatement:tstatementnode;n:tnode);
+
+
 implementation
 implementation
 
 
     uses
     uses
@@ -153,6 +161,28 @@ implementation
       ncal,nflw,rgobj,cgbase
       ncal,nflw,rgobj,cgbase
       ;
       ;
 
 
+
+{*****************************************************************************
+                                     Helpers
+*****************************************************************************}
+
+    function internalstatements(var laststatement:tstatementnode):tblocknode;
+      begin
+        { create dummy initial statement }
+        laststatement := cstatementnode.create(nil,cnothingnode.create);
+        internalstatements := cblocknode.create(laststatement);
+      end;
+
+
+    procedure addstatement(var laststatement:tstatementnode;n:tnode);
+      begin
+        if assigned(laststatement.left) then
+         internalerror(200204201);
+        laststatement.left:=cstatementnode.create(nil,n);
+        laststatement:=tstatementnode(laststatement.left);
+      end;
+
+
 {*****************************************************************************
 {*****************************************************************************
                              TFIRSTNOTHING
                              TFIRSTNOTHING
 *****************************************************************************}
 *****************************************************************************}
@@ -239,6 +269,7 @@ implementation
          firstpass(right);
          firstpass(right);
          if codegenerror then
          if codegenerror then
            exit;
            exit;
+         location.loc:=right.location.loc;
          registers32:=right.registers32;
          registers32:=right.registers32;
          registersfpu:=right.registersfpu;
          registersfpu:=right.registersfpu;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
@@ -306,6 +337,11 @@ implementation
                           (tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
                           (tcallnode(hp.right).procdefinition.proctypeoption=potype_constructor)) and
                       not(is_void(hp.right.resulttype.def)) then
                       not(is_void(hp.right.resulttype.def)) then
                      CGMessage(cg_e_illegal_expression);
                      CGMessage(cg_e_illegal_expression);
+                   { the resulttype of the block is the last type that is
+                     returned. Normally this is a voidtype. But when the
+                     compiler inserts a block of multiple statements then the
+                     last entry can return a value }
+                   resulttype:=hp.right.resulttype;
                 end;
                 end;
               hp:=tstatementnode(hp.left);
               hp:=tstatementnode(hp.left);
            end;
            end;
@@ -389,6 +425,7 @@ implementation
               if hp.registersmmx>registersmmx then
               if hp.registersmmx>registersmmx then
                 registersmmx:=hp.registersmmx;
                 registersmmx:=hp.registersmmx;
 {$endif}
 {$endif}
+              location.loc:=hp.location.loc;
               inc(count);
               inc(count);
               hp:=tstatementnode(hp.left);
               hp:=tstatementnode(hp.left);
            end;
            end;
@@ -456,7 +493,6 @@ implementation
         new(tempinfo);
         new(tempinfo);
         fillchar(tempinfo^,sizeof(tempinfo^),0);
         fillchar(tempinfo^,sizeof(tempinfo^),0);
         tempinfo^.restype := _restype;
         tempinfo^.restype := _restype;
-        tempinfo^.size := _size;
         persistent := _persistent;
         persistent := _persistent;
       end;
       end;
 
 
@@ -470,7 +506,6 @@ implementation
         new(n.tempinfo);
         new(n.tempinfo);
         fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
         fillchar(n.tempinfo^,sizeof(n.tempinfo^),0);
         n.tempinfo^.restype := tempinfo^.restype;
         n.tempinfo^.restype := tempinfo^.restype;
-        n.tempinfo^.size:=size;
 
 
         { signal the temprefs that the temp they point to has been copied, }
         { signal the temprefs that the temp they point to has been copied, }
         { so that if the refs get copied as well, they can hook themselves }
         { so that if the refs get copied as well, they can hook themselves }
@@ -562,6 +597,16 @@ implementation
       begin
       begin
         inherited create(temprefn);
         inherited create(temprefn);
         tempinfo := temp.tempinfo;
         tempinfo := temp.tempinfo;
+        release_to_normal := false;
+        if not temp.persistent then
+          internalerror(200204211);
+      end;
+
+    constructor ttempdeletenode.create_normal_temp(const temp: ttempcreatenode);
+      begin
+        inherited create(temprefn);
+        tempinfo := temp.tempinfo;
+        release_to_normal := true;
       end;
       end;
 
 
     function ttempdeletenode.getcopy: tnode;
     function ttempdeletenode.getcopy: tnode;
@@ -620,7 +665,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.20  2002-04-04 19:05:57  peter
+  Revision 1.21  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.20  2002/04/04 19:05:57  peter
     * removed unused units
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
     * use tlocation.size in cg.a_*loc*() routines
 
 

+ 20 - 4
compiler/ncgbas.pas

@@ -94,6 +94,8 @@ interface
              begin
              begin
                rg.cleartempgen;
                rg.cleartempgen;
                secondpass(tstatementnode(hp).right);
                secondpass(tstatementnode(hp).right);
+               { Compiler inserted blocks can return values }
+               location_copy(location,tstatementnode(hp).right.location);
              end;
              end;
             hp:=tstatementnode(hp).left;
             hp:=tstatementnode(hp).left;
           end;
           end;
@@ -223,7 +225,11 @@ interface
       begin
       begin
         { do second pass on left node }
         { do second pass on left node }
         if assigned(left) then
         if assigned(left) then
-         secondpass(left);
+         begin
+           secondpass(left);
+           { Compiler inserted blocks can return values }
+           location_copy(location,left.location);
+         end;
       end;
       end;
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -255,7 +261,7 @@ interface
         if not tempinfo^.valid then
         if not tempinfo^.valid then
           internalerror(200108231);
           internalerror(200108231);
         { set the temp's location }
         { set the temp's location }
-        location_reset(location,LOC_REFERENCE,int_cgsize(tempinfo^.size));
+        location_reset(location,LOC_REFERENCE,def_cgsize(tempinfo^.restype.def));
         location.reference := tempinfo^.ref;
         location.reference := tempinfo^.ref;
       end;
       end;
 
 
@@ -265,7 +271,10 @@ interface
 
 
     procedure tcgtempdeletenode.pass_2;
     procedure tcgtempdeletenode.pass_2;
       begin
       begin
-        tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
+        if release_to_normal then
+          tg.persistanttemptonormal(tempinfo^.ref.offset)
+        else
+          tg.ungetpersistanttempreference(exprasmlist,tempinfo^.ref);
       end;
       end;
 
 
 
 
@@ -280,7 +289,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.12  2002-04-04 19:05:57  peter
+  Revision 1.13  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.12  2002/04/04 19:05:57  peter
     * removed unused units
     * removed unused units
     * use tlocation.size in cg.a_*loc*() routines
     * use tlocation.size in cg.a_*loc*() routines
 
 

+ 16 - 2
compiler/ncgcnv.pas

@@ -390,8 +390,15 @@ interface
       begin
       begin
         { we reuse the old value }
         { we reuse the old value }
         location_copy(location,left.location);
         location_copy(location,left.location);
+
+        { Floats should never be returned as LOC_CONSTANT, do the
+          moving to memory before the new size is set }
+        if (resulttype.def.deftype=floatdef) and
+           (location.loc=LOC_CONSTANT) then
+         location_force_mem(location);
+
         { but use the new size, but we don't know the size of all arrays }
         { but use the new size, but we don't know the size of all arrays }
-        location.size:=def_cgsize(resulttype.def)
+        location.size:=def_cgsize(resulttype.def);
       end;
       end;
 
 
 
 
@@ -434,7 +441,14 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.10  2002-04-19 15:39:34  peter
+  Revision 1.11  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.10  2002/04/19 15:39:34  peter
     * removed some more routines from cga
     * removed some more routines from cga
     * moved location_force_reg/mem to ncgutil
     * moved location_force_reg/mem to ncgutil
     * moved arrayconstructnode secondpass to ncgld
     * moved arrayconstructnode secondpass to ncgld

+ 9 - 1
compiler/ncgutil.pas

@@ -298,6 +298,7 @@ implementation
           LOC_FPUREGISTER,
           LOC_FPUREGISTER,
           LOC_CFPUREGISTER :
           LOC_CFPUREGISTER :
             begin
             begin
+              tg.gettempofsizereference(exprasmlist,TCGSize2Size[l.size],r);
               cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
               cg.a_loadfpu_reg_ref(exprasmlist,l.size,l.register,r);
               location_reset(l,LOC_REFERENCE,l.size);
               location_reset(l,LOC_REFERENCE,l.size);
               l.reference:=r;
               l.reference:=r;
@@ -382,7 +383,14 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.9  2002-04-21 15:24:38  carl
+  Revision 1.10  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.9  2002/04/21 15:24:38  carl
   + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
   + a_jmp_cond -> a_jmp_always (a_jmp_cond is NOT portable)
   + changeregsize -> rg.makeregsize
   + changeregsize -> rg.makeregsize
 
 

+ 14 - 3
compiler/ncnv.pas

@@ -1485,8 +1485,12 @@ implementation
         if convtype=tc_equal then
         if convtype=tc_equal then
          begin
          begin
            { remove typeconv node if left is a const. For other nodes we can't
            { remove typeconv node if left is a const. For other nodes we can't
-             remove it because the secondpass can still depend on the old type (PFV) }
-           if is_constnode(left) then
+             remove it because the secondpass can still depend on the old type (PFV)
+             Conversions to float should also be left in the tree, because a float
+             is not possible in LOC_CONSTANT. The second_nothing routine will take
+             care of the conversion to LOC_REFERENCE }
+           if is_constnode(left) and
+              (resulttype.def.deftype<>floatdef) then
             begin
             begin
               left.resulttype:=resulttype;
               left.resulttype:=resulttype;
               result:=left;
               result:=left;
@@ -1701,7 +1705,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.51  2002-04-06 18:10:42  jonas
+  Revision 1.52  2002-04-21 19:02:03  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.51  2002/04/06 18:10:42  jonas
     * several powerpc-related additions and fixes
     * several powerpc-related additions and fixes
 
 
   Revision 1.50  2002/04/04 19:05:58  peter
   Revision 1.50  2002/04/04 19:05:58  peter

+ 13 - 8
compiler/nld.pas

@@ -275,14 +275,12 @@ implementation
                    { process methodpointer }
                    { process methodpointer }
                    if assigned(left) then
                    if assigned(left) then
                     begin
                     begin
-                      { if only typenode then remove }
+                      resulttypepass(left);
+
+                      { turn on the allowed flag, the secondpass
+                        will handle the typen itself }
                       if left.nodetype=typen then
                       if left.nodetype=typen then
-                       begin
-                         left.free;
-                         left:=nil;
-                       end
-                      else
-                       resulttypepass(left);
+                       ttypenode(left).allowed:=true;
                     end;
                     end;
                 end;
                 end;
            else
            else
@@ -915,7 +913,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.34  2002-04-02 17:11:29  peter
+  Revision 1.35  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.34  2002/04/02 17:11:29  peter
     * tlocation,treference update
     * tlocation,treference update
     * LOC_CONSTANT added for better constant handling
     * LOC_CONSTANT added for better constant handling
     * secondadd splitted in multiple routines
     * secondadd splitted in multiple routines

+ 18 - 158
compiler/nmem.pas

@@ -40,19 +40,13 @@ interface
        tloadvmtnodeclass = class of tloadvmtnode;
        tloadvmtnodeclass = class of tloadvmtnode;
 
 
        thnewnode = class(tnode)
        thnewnode = class(tnode)
-          constructor create;virtual;
+          objtype : ttype;
+          constructor create(t:ttype);virtual;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function det_resulttype:tnode;override;
           function det_resulttype:tnode;override;
        end;
        end;
        thnewnodeclass = class of thnewnode;
        thnewnodeclass = class of thnewnode;
 
 
-       tnewnode = class(tunarynode)
-          constructor create(l : tnode);virtual;
-          function pass_1 : tnode;override;
-          function det_resulttype:tnode;override;
-       end;
-       tnewnodeclass = class of tnewnode;
-
        thdisposenode = class(tunarynode)
        thdisposenode = class(tunarynode)
           constructor create(l : tnode);virtual;
           constructor create(l : tnode);virtual;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
@@ -60,13 +54,6 @@ interface
        end;
        end;
        thdisposenodeclass = class of thdisposenode;
        thdisposenodeclass = class of thdisposenode;
 
 
-       tsimplenewdisposenode = class(tunarynode)
-          constructor create(n : tnodetype;l : tnode);
-          function pass_1 : tnode;override;
-          function det_resulttype:tnode;override;
-       end;
-       tsimplenewdisposenodeclass = class of tsimplenewdisposenode;
-
        taddrnode = class(tunarynode)
        taddrnode = class(tunarynode)
           getprocvardef : tprocvardef;
           getprocvardef : tprocvardef;
           constructor create(l : tnode);virtual;
           constructor create(l : tnode);virtual;
@@ -130,9 +117,7 @@ interface
     var
     var
        cloadvmtnode : tloadvmtnodeclass;
        cloadvmtnode : tloadvmtnodeclass;
        chnewnode : thnewnodeclass;
        chnewnode : thnewnodeclass;
-       cnewnode : tnewnodeclass;
        chdisposenode : thdisposenodeclass;
        chdisposenode : thdisposenodeclass;
-       csimplenewdisposenode : tsimplenewdisposenodeclass;
        caddrnode : taddrnodeclass;
        caddrnode : taddrnodeclass;
        cdoubleaddrnode : tdoubleaddrnodeclass;
        cdoubleaddrnode : tdoubleaddrnodeclass;
        cderefnode : tderefnodeclass;
        cderefnode : tderefnodeclass;
@@ -147,6 +132,7 @@ implementation
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
       symconst,symbase,types,
       symconst,symbase,types,
+      nbas,
       htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase
       htypechk,pass_1,ncal,nld,ncon,ncnv,cgbase
       ;
       ;
 
 
@@ -180,16 +166,19 @@ implementation
                              THNEWNODE
                              THNEWNODE
 *****************************************************************************}
 *****************************************************************************}
 
 
-    constructor thnewnode.create;
+    constructor thnewnode.create(t:ttype);
       begin
       begin
          inherited create(hnewn);
          inherited create(hnewn);
+         objtype:=t;
       end;
       end;
 
 
 
 
     function thnewnode.det_resulttype:tnode;
     function thnewnode.det_resulttype:tnode;
       begin
       begin
         result:=nil;
         result:=nil;
-        resulttype:=voidtype;
+        if objtype.def.deftype<>objectdef then
+          Message(parser_e_pointer_to_class_expected);
+        resulttype:=objtype;
       end;
       end;
 
 
 
 
@@ -199,100 +188,6 @@ implementation
       end;
       end;
 
 
 
 
-{*****************************************************************************
-                              TNEWNODE
-*****************************************************************************}
-
-    constructor tnewnode.create(l : tnode);
-      begin
-         inherited create(newn,l);
-      end;
-
-
-    function tnewnode.det_resulttype:tnode;
-      begin
-        result:=nil;
-        if assigned(left) then
-         resulttypepass(left);
-        resulttype:=voidtype;
-      end;
-
-
-    function tnewnode.pass_1 : tnode;
-{$ifdef NEW_COMPILERPROC}
-      var
-        temp          : ttempcreatenode;
-        newstatement  : tstatementnode;
-        newblock      : tblocknode;
-{$endif NEW_COMPILERPROC}
-      begin
-         result:=nil;
-{$ifdef NEW_COMPILERPROC}
-         { create the blocknode which will hold the generated statements + }
-         { an initial dummy statement                                      }
-         newstatement := cstatementnode.create(nil,cnothingnode.create);
-         newblock := cblocknode.create(newstatement);
-
-         { create temp for result }
-         temp := ctempcreatenode.create(resulttype,
-                                        resulttype.size,true);
-         newstatement.left := cstatementnode.create(nil,temp);
-
-         { create parameter }
-         sizepara := ccallparanode.create(cordconstnode.create
-             (tpointerdef(resulttype.def).pointertype.def.size,s32bittype),nil);
-
-         { create the call and assign the result to dest  }
-         { the assignment will take care of rangechecking }
-         newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
-           ctemprefnode.create(tempcode),
-           ccallnode.createintern('fpc_getmem',sizepara)));
-         newstatement := tstatementnode(newstatement.left);
-
-         if tpointerdef(resulttype.def).pointertype.def.needs_inittable then
-          begin
-            para := ccallparanode.create(cloadnode.create
-                       (tpointerdef(resulttype.def).pointertype.def.size,s32bittype),
-                    ccallparanode.create(cordconstnode.create
-                       (tpointerdef(resulttype.def).pointertype.def.size,s32bittype),nil));
-            newstatement.left := cstatementnode.create(nil,cassignmentnode.create(
-            ctemprefnode.create(tempcode),
-            ccallnode.createintern('fpc_initialize',sizepara)));
-            newstatement := tstatementnode(newstatement.left);
-            new(r);
-            reset_reference(r^);
-            r^.symbol:=tstoreddef(tpointerdef(resulttype.def).pointertype.def).get_rtti_label(initrtti);
-            emitpushreferenceaddr(r^);
-            dispose(r);
-            { push pointer we just allocated, we need to initialize the
-              data located at that pointer not the pointer self (PFV) }
-            emit_push_loc(location);
-            emitcall('FPC_INITIALIZE');
-          end;
-
-         { and return it }
-         result := newblock;
-{$endif NEW_COMPILERPROC}
-
-         if assigned(left) then
-          begin
-            firstpass(left);
-            if codegenerror then
-             exit;
-
-            registers32:=left.registers32;
-            registersfpu:=left.registersfpu;
-{$ifdef SUPPORT_MMX}
-            registersmmx:=left.registersmmx;
-{$endif SUPPORT_MMX}
-            location.loc:=LOC_REGISTER
-          end
-         else
-          location.loc:=LOC_REFERENCE;
-         procinfo^.flags:=procinfo^.flags or pi_do_call;
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                             THDISPOSENODE
                             THDISPOSENODE
 *****************************************************************************}
 *****************************************************************************}
@@ -309,6 +204,8 @@ implementation
         resulttypepass(left);
         resulttypepass(left);
         if codegenerror then
         if codegenerror then
          exit;
          exit;
+        if (left.resulttype.def.deftype<>pointerdef) then
+          CGMessage1(type_e_pointer_type_expected,left.resulttype.def.typename);
         resulttype:=tpointerdef(left.resulttype.def).pointertype;
         resulttype:=tpointerdef(left.resulttype.def).pointertype;
       end;
       end;
 
 
@@ -337,48 +234,6 @@ implementation
       end;
       end;
 
 
 
 
-{*****************************************************************************
-                        TSIMPLENEWDISPOSENODE
-*****************************************************************************}
-
-    constructor tsimplenewdisposenode.create(n : tnodetype;l : tnode);
-
-      begin
-         inherited create(n,l);
-      end;
-
-
-    function tsimplenewdisposenode.det_resulttype:tnode;
-      begin
-        result:=nil;
-        resulttypepass(left);
-        if codegenerror then
-         exit;
-        if (left.resulttype.def.deftype<>pointerdef) then
-          CGMessage1(type_e_pointer_type_expected,left.resulttype.def.typename);
-        resulttype:=voidtype;
-      end;
-
-
-    function tsimplenewdisposenode.pass_1 : tnode;
-      begin
-         result:=nil;
-         { this cannot be in a register !! }
-         make_not_regable(left);
-
-         firstpass(left);
-         if codegenerror then
-          exit;
-
-         registers32:=left.registers32;
-         registersfpu:=left.registersfpu;
-{$ifdef SUPPORT_MMX}
-         registersmmx:=left.registersmmx;
-{$endif SUPPORT_MMX}
-         procinfo^.flags:=procinfo^.flags or pi_do_call;
-      end;
-
-
 {*****************************************************************************
 {*****************************************************************************
                              TADDRNODE
                              TADDRNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -1027,9 +882,7 @@ implementation
 begin
 begin
   cloadvmtnode := tloadvmtnode;
   cloadvmtnode := tloadvmtnode;
   chnewnode := thnewnode;
   chnewnode := thnewnode;
-  cnewnode := tnewnode;
   chdisposenode := thdisposenode;
   chdisposenode := thdisposenode;
-  csimplenewdisposenode := tsimplenewdisposenode;
   caddrnode := taddrnode;
   caddrnode := taddrnode;
   cdoubleaddrnode := tdoubleaddrnode;
   cdoubleaddrnode := tdoubleaddrnode;
   cderefnode := tderefnode;
   cderefnode := tderefnode;
@@ -1040,7 +893,14 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.28  2002-04-20 21:32:23  carl
+  Revision 1.29  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.28  2002/04/20 21:32:23  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 8 - 9
compiler/node.pas

@@ -86,8 +86,6 @@ interface
           typen,           {A type name. Used for i.e. typeof(obj).}
           typen,           {A type name. Used for i.e. typeof(obj).}
           hnewn,           {The new operation, constructor call.}
           hnewn,           {The new operation, constructor call.}
           hdisposen,       {The dispose operation with destructor call.}
           hdisposen,       {The dispose operation with destructor call.}
-          newn,     {The new operation, constructor call.}
-          simpledisposen,  {The dispose operation.}
           setelementn,     {A set element(s) (i.e. [a,b] and also [a..b]).}
           setelementn,     {A set element(s) (i.e. [a,b] and also [a..b]).}
           setconstn,       {A set constant (i.e. [1,2]).}
           setconstn,       {A set constant (i.e. [1,2]).}
           blockn,         {A block of statements.}
           blockn,         {A block of statements.}
@@ -104,10 +102,8 @@ interface
           casen,           {A case statement.}
           casen,           {A case statement.}
           labeln,         {A label.}
           labeln,         {A label.}
           goton,           {A goto statement.}
           goton,           {A goto statement.}
-          simplenewn,      {The new operation.}
           tryexceptn,      {A try except block.}
           tryexceptn,      {A try except block.}
           raisen,         {A raise statement.}
           raisen,         {A raise statement.}
-          switchesn,       {??? Currently unused...}
           tryfinallyn,     {A try finally statement.}
           tryfinallyn,     {A try finally statement.}
           onn,       { for an on statement in exception code }
           onn,       { for an on statement in exception code }
           isn,       {Represents the is operator.}
           isn,       {Represents the is operator.}
@@ -175,8 +171,6 @@ interface
           'typen',
           'typen',
           'hnewn',
           'hnewn',
           'hdisposen',
           'hdisposen',
-          'newn',
-          'simpledisposen',
           'setelementn',
           'setelementn',
           'setconstn',
           'setconstn',
           'blockn',
           'blockn',
@@ -193,10 +187,8 @@ interface
           'casen',
           'casen',
           'labeln',
           'labeln',
           'goton',
           'goton',
-          'simplenewn',
           'tryexceptn',
           'tryexceptn',
           'raisen',
           'raisen',
-          'switchesn',
           'tryfinallyn',
           'tryfinallyn',
           'onn',
           'onn',
           'isn',
           'isn',
@@ -814,7 +806,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.23  2002-04-06 18:13:01  jonas
+  Revision 1.24  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.23  2002/04/06 18:13:01  jonas
     * several powerpc-related additions and fixes
     * several powerpc-related additions and fixes
 
 
   Revision 1.22  2002/03/31 20:26:35  jonas
   Revision 1.22  2002/03/31 20:26:35  jonas

+ 11 - 2
compiler/options.pas

@@ -382,6 +382,7 @@ begin
                         'l' : include(initglobalswitches,cs_asm_source);
                         'l' : include(initglobalswitches,cs_asm_source);
                         'r' : include(initglobalswitches,cs_asm_regalloc);
                         'r' : include(initglobalswitches,cs_asm_regalloc);
                         't' : include(initglobalswitches,cs_asm_tempalloc);
                         't' : include(initglobalswitches,cs_asm_tempalloc);
+                        'n' : include(initglobalswitches,cs_asm_nodes);
                         '-' : initglobalswitches:=initglobalswitches -
                         '-' : initglobalswitches:=initglobalswitches -
                                 [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
                                 [cs_asm_leave, cs_asm_source,cs_asm_regalloc, cs_asm_tempalloc];
                        else
                        else
@@ -1345,6 +1346,7 @@ begin
   def_symbol('HAS_ADDR_STACK_ON_STACK');
   def_symbol('HAS_ADDR_STACK_ON_STACK');
   def_symbol('NOBOUNDCHECK');
   def_symbol('NOBOUNDCHECK');
   def_symbol('HASCOMPILERPROC');
   def_symbol('HASCOMPILERPROC');
+  def_symbol('VALUEGETMEM');
   def_symbol('VALUEFREEMEM');
   def_symbol('VALUEFREEMEM');
 
 
   { some stuff for TP compatibility }
   { some stuff for TP compatibility }
@@ -1379,7 +1381,7 @@ begin
    else
    else
         internalerror(1295969);
         internalerror(1295969);
   end;
   end;
-      
+
 
 
 { get default messagefile }
 { get default messagefile }
 {$ifdef Delphi}
 {$ifdef Delphi}
@@ -1656,7 +1658,14 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.68  2002-04-20 21:32:24  carl
+  Revision 1.69  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.68  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 65 - 57
compiler/pass_2.pas

@@ -47,7 +47,7 @@ procedure secondpass(var p : tnode);
 implementation
 implementation
 
 
    uses
    uses
-{$ifdef logsecondpass}
+{$ifdef EXTDEBUG}
      cutils,
      cutils,
 {$endif}
 {$endif}
      globtype,systems,verbose,
      globtype,systems,verbose,
@@ -59,7 +59,7 @@ implementation
                               SecondPass
                               SecondPass
 *****************************************************************************}
 *****************************************************************************}
 
 
-{$ifdef logsecondpass}
+{$ifdef EXTDEBUG}
      procedure logsecond(ht:tnodetype; entry: boolean);
      procedure logsecond(ht:tnodetype; entry: boolean);
        const
        const
          secondnames: array[tnodetype] of string[13] =
          secondnames: array[tnodetype] of string[13] =
@@ -92,9 +92,8 @@ implementation
              'ordconst',    {ordconstn}
              'ordconst',    {ordconstn}
              'typeconv',    {typeconvn}
              'typeconv',    {typeconvn}
              'calln',       {calln}
              'calln',       {calln}
-             'nothing-callp',     {callparan}
+             'noth-callpar',     {callparan}
              'realconst',   {realconstn}
              'realconst',   {realconstn}
-             'fixconst',    {fixconstn}
              'unaryminus',  {unaryminusn}
              'unaryminus',  {unaryminusn}
              'asm',         {asmn}
              'asm',         {asmn}
              'vecn',        {vecn}
              'vecn',        {vecn}
@@ -109,8 +108,6 @@ implementation
              'nothing-typen',     {typen}
              'nothing-typen',     {typen}
              'hnewn',       {hnewn}
              'hnewn',       {hnewn}
              'hdisposen',   {hdisposen}
              'hdisposen',   {hdisposen}
-             'newn',        {newn}
-             'simplenewDISP', {simpledisposen}
              'setelement',  {setelementn}
              'setelement',  {setelementn}
              'setconst',    {setconstn}
              'setconst',    {setconstn}
              'blockn',      {blockn}
              'blockn',      {blockn}
@@ -127,22 +124,25 @@ implementation
              'case',        {casen}
              'case',        {casen}
              'label',       {labeln}
              'label',       {labeln}
              'goto',        {goton}
              'goto',        {goton}
-             'simpleNEWdisp', {simplenewn}
              'tryexcept',   {tryexceptn}
              'tryexcept',   {tryexceptn}
              'raise',       {raisen}
              'raise',       {raisen}
-             'nothing-swtch',     {switchesn}
              'tryfinally',  {tryfinallyn}
              'tryfinally',  {tryfinallyn}
              'on',    {onn}
              'on',    {onn}
              'is',    {isn}
              'is',    {isn}
              'as',    {asn}
              'as',    {asn}
              'error-caret',       {caretn}
              'error-caret',       {caretn}
              'fail',        {failn}
              'fail',        {failn}
-             'add-startstar',  {starstarn}
+             'add-starstar',  {starstarn}
              'procinline',  {procinlinen}
              'procinline',  {procinlinen}
              'arrayconstruc', {arrayconstructn}
              'arrayconstruc', {arrayconstructn}
              'noth-arrcnstr',     {arrayconstructrangen}
              'noth-arrcnstr',     {arrayconstructrangen}
+             'tempn',
+             'temprefn',
+             'addoptn',
              'nothing-nothg',     {nothingn}
              'nothing-nothg',     {nothingn}
-             'loadvmt'      {loadvmtn}
+             'loadvmt',      {loadvmtn}
+             'guidconstn',
+             'rttin'
              );
              );
       var
       var
         p: pchar;
         p: pchar;
@@ -153,7 +153,7 @@ implementation
           p := strpnew('second'+secondnames[ht]+' (exit)');
           p := strpnew('second'+secondnames[ht]+' (exit)');
         exprasmlist.concat(tai_asm_comment.create(p));
         exprasmlist.concat(tai_asm_comment.create(p));
       end;
       end;
-{$endif logsecondpass}
+{$endif EXTDEBUG}
 
 
      procedure secondpass(var p : tnode);
      procedure secondpass(var p : tnode);
       var
       var
@@ -184,15 +184,13 @@ implementation
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
             oldloc:=p.location.loc;
             oldloc:=p.location.loc;
             p.location.loc:=LOC_INVALID;
             p.location.loc:=LOC_INVALID;
+            if (cs_asm_nodes in aktglobalswitches) then
+              logsecond(p.nodetype,true);
 {$endif EXTDEBUG}
 {$endif EXTDEBUG}
-{$ifdef logsecondpass}
-            logsecond(p.nodetype,true);
-{$endif logsecondpass}
             p.pass_2;
             p.pass_2;
-{$ifdef logsecondpass}
-            logsecond(p.nodetype,false);
-{$endif logsecondpass}
 {$ifdef EXTDEBUG}
 {$ifdef EXTDEBUG}
+            if (cs_asm_nodes in aktglobalswitches) then
+              logsecond(p.nodetype,false);
             if (not codegenerror) and
             if (not codegenerror) and
                (oldloc<>LOC_INVALID) and
                (oldloc<>LOC_INVALID) and
                (p.location.loc=LOC_INVALID) then
                (p.location.loc=LOC_INVALID) then
@@ -256,48 +254,51 @@ implementation
          { only do secondpass if there are no errors }
          { only do secondpass if there are no errors }
          if ErrorCount=0 then
          if ErrorCount=0 then
            begin
            begin
+{$ifdef OMITSTACKFRAME}
              if (cs_regalloc in aktglobalswitches) and
              if (cs_regalloc in aktglobalswitches) and
                 ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
                 ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
                begin
                begin
-                                   { can we omit the stack frame ? }
-                                   { conditions:
-                                     1. procedure (not main block)
-                                     2. no constructor or destructor
-                                     3. no call to other procedures
-                                     4. no interrupt handler
-                                   }
-                                   {!!!!!! this doesn work yet, because of problems with
-                                      with linux and windows
-                                   }
-                                   (*
-                                   if assigned(aktprocsym) then
-                                     begin
-                                       if not(assigned(procinfo^._class)) and
-                                          not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
-                                          not(po_interrupt in aktprocdef.procoptions) and
-                                          ((procinfo^.flags and pi_do_call)=0) and
-                                          (lexlevel>=normal_function_level) then
-                                         begin
-                                          { use ESP as frame pointer }
-                                           procinfo^.framepointer:=STACK_POINTER_REG;
-                                           use_esp_stackframe:=true;
-
-                                          { calc parameter distance new }
-                                           dec(procinfo^.framepointer_offset,4);
-                                           dec(procinfo^.selfpointer_offset,4);
-
-                                          { is this correct ???}
-                                          { retoffset can be negativ for results in eax !! }
-                                          { the value should be decreased only if positive }
-                                           if procinfo^.retoffset>=0 then
-                                             dec(procinfo^.retoffset,4);
-
-                                           dec(procinfo^.para_offset,4);
-                                           aktprocdef.parast.address_fixup:=procinfo^.para_offset;
-                                         end;
-                                     end;
-                                    *)
-                                  end;
+                 { can we omit the stack frame ? }
+                 { conditions:
+                   1. procedure (not main block)
+                   2. no constructor or destructor
+                   3. no call to other procedures
+                   4. no interrupt handler
+                 }
+                 {!!!!!! this doesn work yet, because of problems with
+                    with linux and windows
+                 }
+                 (*
+                 if assigned(aktprocsym) then
+                   begin
+                     if not(assigned(procinfo^._class)) and
+                        not(aktprocdef.proctypeoption in [potype_constructor,potype_destructor]) and
+                        not(po_interrupt in aktprocdef.procoptions) and
+                        ((procinfo^.flags and pi_do_call)=0) and
+                        (lexlevel>=normal_function_level) then
+                       begin
+                        { use ESP as frame pointer }
+                         procinfo^.framepointer:=STACK_POINTER_REG;
+                         use_esp_stackframe:=true;
+
+                        { calc parameter distance new }
+                         dec(procinfo^.framepointer_offset,4);
+                         dec(procinfo^.selfpointer_offset,4);
+
+                        { is this correct ???}
+                        { retoffset can be negativ for results in eax !! }
+                        { the value should be decreased only if positive }
+                         if procinfo^.retoffset>=0 then
+                           dec(procinfo^.retoffset,4);
+
+                         dec(procinfo^.para_offset,4);
+                         aktprocdef.parast.address_fixup:=procinfo^.para_offset;
+                       end;
+                   end;
+                  *)
+                end;
+{$endif OMITSTACKFRAME}
+
               { process register variable stuff (JM) }
               { process register variable stuff (JM) }
               assign_regvars(p);
               assign_regvars(p);
               load_regvars(procinfo^.aktentrycode,p);
               load_regvars(procinfo^.aktentrycode,p);
@@ -320,7 +321,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.25  2002-04-20 21:32:24  carl
+  Revision 1.26  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.25  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 9 - 1
compiler/pdecobj.pas

@@ -794,6 +794,7 @@ implementation
           p:=comp_expr(true);
           p:=comp_expr(true);
           if p.nodetype=stringconstn then
           if p.nodetype=stringconstn then
             begin
             begin
+              stringdispose(aktclass.iidstr);
               aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
               aktclass.iidstr:=stringdup(strpas(tstringconstnode(p).value_str)); { or upper? }
               p.free;
               p.free;
               aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
               aktclass.isiidguidvalid:=string2guid(aktclass.iidstr^,aktclass.iidguid);
@@ -1110,7 +1111,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.40  2002-04-19 15:46:02  peter
+  Revision 1.41  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.40  2002/04/19 15:46:02  peter
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
     * mangledname rewrite, tprocdef.mangledname is now created dynamicly
       in most cases and not written to the ppu
       in most cases and not written to the ppu
     * add mangeledname_prefix() routine to generate the prefix of
     * add mangeledname_prefix() routine to generate the prefix of

+ 37 - 24
compiler/pdecsub.pas

@@ -329,7 +329,6 @@ implementation
         orgsp,sp:stringid;
         orgsp,sp:stringid;
         paramoffset:longint;
         paramoffset:longint;
         sym:tsym;
         sym:tsym;
-        doinsert : boolean;
         st : tsymtable;
         st : tsymtable;
         srsymtable : tsymtable;
         srsymtable : tsymtable;
         pdl     : pprocdeflist;
         pdl     : pprocdeflist;
@@ -478,7 +477,6 @@ implementation
              end;
              end;
          end;
          end;
 
 
-        doinsert:=true;
         if assigned(aktprocsym) then
         if assigned(aktprocsym) then
          begin
          begin
            { Check if overloaded is a procsym }
            { Check if overloaded is a procsym }
@@ -498,8 +496,9 @@ implementation
                   Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
                   Message1(parser_e_overloaded_no_procedure,aktprocsym.realname)
                  else
                  else
                   DuplicateSym(aktprocsym);
                   DuplicateSym(aktprocsym);
-                 { don't reinsert as that will generated another error }
-                 doinsert:=false;
+                 { rename the name to an unique name to avoid an
+                   error when inserting the symbol in the symtable }
+                 orgsp:=orgsp+'$'+tostr(aktfilepos.line);
                end;
                end;
               { generate a new aktprocsym }
               { generate a new aktprocsym }
               aktprocsym:=nil;
               aktprocsym:=nil;
@@ -537,8 +536,7 @@ implementation
              end
              end
             else
             else
              aktprocsym:=tprocsym.create(orgsp);
              aktprocsym:=tprocsym.create(orgsp);
-            if doinsert then
-             symtablestack.insert(aktprocsym);
+            symtablestack.insert(aktprocsym);
          end;
          end;
 
 
         st:=symtablestack;
         st:=symtablestack;
@@ -1908,23 +1906,31 @@ const
 
 
         { insert otsym only in the right symtable }
         { insert otsym only in the right symtable }
         if ((procinfo^.flags and pi_operator)<>0) and
         if ((procinfo^.flags and pi_operator)<>0) and
-           assigned(otsym) and
-           not parse_only then
-          begin
-            if ret_in_param(aprocdef.rettype.def) then
-              begin
-                aprocdef.parast.insert(otsym);
-                { this increases the data size }
-                { correct this to get the right ret $value }
-                dec(aprocdef.parast.datasize,
-                    align(otsym.getpushsize,aktprocdef.parast.dataalignment));
-                { this allows to read the funcretoffset }
-                otsym.address:=-4;
-                otsym.varspez:=vs_var;
-              end
-            else
-              aprocdef.localst.insert(otsym);
-          end;
+           assigned(otsym) then
+         begin
+           if not parse_only then
+            begin
+              if ret_in_param(aprocdef.rettype.def) then
+               begin
+                 aprocdef.parast.insert(otsym);
+                 { this increases the data size }
+                 { correct this to get the right ret $value }
+                 dec(aprocdef.parast.datasize,
+                     align(otsym.getpushsize,aktprocdef.parast.dataalignment));
+                 { this allows to read the funcretoffset }
+                 otsym.address:=-4;
+                 otsym.varspez:=vs_var;
+               end
+              else
+               aprocdef.localst.insert(otsym);
+            end
+           else
+            begin
+              { this is not required anymore }
+              otsym.free;
+              otsym:=nil;
+            end;
+         end;
 
 
         proc_add_definition:=forwardfound;
         proc_add_definition:=forwardfound;
       end;
       end;
@@ -1932,7 +1938,14 @@ const
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.52  2002-04-20 21:32:24  carl
+  Revision 1.53  2002-04-21 19:02:04  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.52  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 106 - 20
compiler/pexpr.pas

@@ -220,6 +220,9 @@ implementation
 
 
     function new_dispose_statement(is_new:boolean) : tnode;
     function new_dispose_statement(is_new:boolean) : tnode;
       var
       var
+        newstatement : tstatementnode;
+        temp         : ttempcreatenode;
+        para         : tcallparanode;
         p,p2     : tnode;
         p,p2     : tnode;
         again    : boolean; { dummy for do_proc_call }
         again    : boolean; { dummy for do_proc_call }
         destructorname : stringid;
         destructorname : stringid;
@@ -293,11 +296,10 @@ implementation
             else
             else
               begin
               begin
                 if is_new then
                 if is_new then
-                 p2:=chnewnode.create
+                 p2:=chnewnode.create(tpointerdef(p.resulttype.def).pointertype)
                 else
                 else
                  p2:=chdisposenode.create(p);
                  p2:=chdisposenode.create(p);
                 do_resulttypepass(p2);
                 do_resulttypepass(p2);
-                p2.resulttype:=tpointerdef(p.resulttype.def).pointertype;
                 if is_new then
                 if is_new then
                   do_member_read(false,sym,p2,again)
                   do_member_read(false,sym,p2,again)
                 else
                 else
@@ -329,8 +331,6 @@ implementation
                     begin
                     begin
                       if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
                       if (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor) then
                         Message(parser_e_expr_have_to_be_constructor_call);
                         Message(parser_e_expr_have_to_be_constructor_call);
-                      p2:=cnewnode.create(p2);
-                      do_resulttypepass(p2);
                       p2.resulttype:=p.resulttype;
                       p2.resulttype:=p.resulttype;
                       p2:=cassignmentnode.create(p,p2);
                       p2:=cassignmentnode.create(p,p2);
                     end
                     end
@@ -365,10 +365,57 @@ implementation
                        Message(parser_e_no_new_dispose_on_void_pointers);
                        Message(parser_e_no_new_dispose_on_void_pointers);
                     end;
                     end;
 
 
+                  { create statements with call to getmem+initialize or
+                    finalize+freemem }
+                  new_dispose_statement:=internalstatements(newstatement);
+
                   if is_new then
                   if is_new then
-                    new_dispose_statement:=csimplenewdisposenode.create(simplenewn,p)
+                   begin
+                     { create temp for result }
+                     temp := ctempcreatenode.create(p.resulttype,p.resulttype.def.size,true);
+                     addstatement(newstatement,temp);
+
+                     { create call to fpc_getmem }
+                     para := ccallparanode.create(cordconstnode.create
+                         (tpointerdef(p.resulttype.def).pointertype.def.size,s32bittype),nil);
+                     addstatement(newstatement,cassignmentnode.create(
+                         ctemprefnode.create(temp),
+                         ccallnode.createintern('fpc_getmem',para)));
+
+                     { create call to fpc_initialize }
+                     if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
+                      begin
+                        para := ccallparanode.create(caddrnode.create(crttinode.create(
+                                   tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
+                                ccallparanode.create(ctemprefnode.create
+                                   (temp),nil));
+                        addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));
+                      end;
+
+                     { copy the temp to the destination }
+                     addstatement(newstatement,cassignmentnode.create(
+                         p,
+                         ctemprefnode.create(temp)));
+
+                     { release temp }
+                     addstatement(newstatement,ctempdeletenode.create(temp));
+                   end
                   else
                   else
-                    new_dispose_statement:=csimplenewdisposenode.create(simpledisposen,p);
+                   begin
+                     { create call to fpc_finalize }
+                     if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
+                      begin
+                        { we need to use a copy of p here }
+                        para := ccallparanode.create(caddrnode.create(crttinode.create
+                                   (tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
+                                ccallparanode.create(p.getcopy,nil));
+                        addstatement(newstatement,ccallnode.createintern('fpc_finalize',para));
+                      end;
+
+                     { create call to fpc_freemem }
+                     para := ccallparanode.create(p,nil);
+                     addstatement(newstatement,ccallnode.createintern('fpc_freemem',para));
+                   end;
                end;
                end;
           end;
           end;
         consume(_RKLAMMER);
         consume(_RKLAMMER);
@@ -377,6 +424,10 @@ implementation
 
 
     function new_function : tnode;
     function new_function : tnode;
       var
       var
+        newstatement : tstatementnode;
+        newblock     : tblocknode;
+        temp         : ttempcreatenode;
+        para         : tcallparanode;
         p1,p2  : tnode;
         p1,p2  : tnode;
         classh : tobjectdef;
         classh : tobjectdef;
         sym    : tsym;
         sym    : tsym;
@@ -399,26 +450,52 @@ implementation
           begin
           begin
             if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
             if (tpointerdef(p1.resulttype.def).pointertype.def.deftype=objectdef) and
                (oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions)  then
                (oo_has_vmt in tobjectdef(tpointerdef(p1.resulttype.def).pointertype.def).objectoptions)  then
-             Message(parser_w_use_extended_syntax_for_objects);
-            p2:=cnewnode.create(nil);
-            do_resulttypepass(p2);
-            p2.resulttype:=p1.resulttype;
+              Message(parser_w_use_extended_syntax_for_objects);
+
+            { create statements with call to getmem+initialize }
+            newblock:=internalstatements(newstatement);
+
+            { create temp for result }
+            temp := ctempcreatenode.create(p1.resulttype,p1.resulttype.def.size,true);
+            addstatement(newstatement,temp);
+
+            { create call to fpc_getmem }
+            para := ccallparanode.create(cordconstnode.create
+                (tpointerdef(p1.resulttype.def).pointertype.def.size,s32bittype),nil);
+            addstatement(newstatement,cassignmentnode.create(
+                ctemprefnode.create(temp),
+                ccallnode.createintern('fpc_getmem',para)));
+
+            { create call to fpc_initialize }
+            if tpointerdef(p1.resulttype.def).pointertype.def.needs_inittable then
+             begin
+               para := ccallparanode.create(caddrnode.create(crttinode.create
+                          (tstoreddef(tpointerdef(p1.resulttype.def).pointertype.def),initrtti)),
+                       ccallparanode.create(ctemprefnode.create
+                          (temp),nil));
+               addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));
+             end;
+
+            { the last statement should return the value as
+              location and type, this is done be referencing the
+              temp and converting it first from a persistent temp to
+              normal temp }
+            addstatement(newstatement,ctempdeletenode.create_normal_temp(temp));
+            addstatement(newstatement,ctemprefnode.create(temp));
+
             p1.destroy;
             p1.destroy;
-            p1:=p2;
+            p1:=newblock;
             consume(_RKLAMMER);
             consume(_RKLAMMER);
           end
           end
         else
         else
           begin
           begin
-            p2:=chnewnode.create;
+            p2:=chnewnode.create(tpointerdef(p1.resulttype.def).pointertype);
             do_resulttypepass(p2);
             do_resulttypepass(p2);
-            p2.resulttype:=tpointerdef(p1.resulttype.def).pointertype;
             consume(_COMMA);
             consume(_COMMA);
             afterassignment:=false;
             afterassignment:=false;
             { determines the current object defintion }
             { determines the current object defintion }
             classh:=tobjectdef(p2.resulttype.def);
             classh:=tobjectdef(p2.resulttype.def);
-            if classh.deftype<>objectdef then
-             Message(parser_e_pointer_to_class_expected)
-            else
+            if classh.deftype=objectdef then
              begin
              begin
                { check for an abstract class }
                { check for an abstract class }
                if (oo_has_abstract in classh.objectoptions) then
                if (oo_has_abstract in classh.objectoptions) then
@@ -434,9 +511,11 @@ implementation
                   (assigned(tcallnode(p2).procdefinition) and
                   (assigned(tcallnode(p2).procdefinition) and
                    (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
                    (tcallnode(p2).procdefinition.proctypeoption<>potype_constructor)) then
                 Message(parser_e_expr_have_to_be_constructor_call);
                 Message(parser_e_expr_have_to_be_constructor_call);
-             end;
-            p2:=cnewnode.create(p2);
-            do_resulttypepass(p2);
+             end
+            else
+             Message(parser_e_pointer_to_class_expected);
+            { constructors return boolean, update resulttype to return
+              the pointer to the object }
             p2.resulttype:=p1.resulttype;
             p2.resulttype:=p1.resulttype;
             p1.destroy;
             p1.destroy;
             p1:=p2;
             p1:=p2;
@@ -2458,7 +2537,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.62  2002-04-16 16:11:17  peter
+  Revision 1.63  2002-04-21 19:02:05  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.62  2002/04/16 16:11:17  peter
     * using inherited; without a parent having the same function
     * using inherited; without a parent having the same function
       will do nothing like delphi
       will do nothing like delphi
 
 

+ 13 - 6
compiler/pstatmnt.pas

@@ -991,8 +991,8 @@ implementation
              { 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)    }
              { the same is true for val() if the third parameter is not 32 bit }
              { the same is true for val() if the third parameter is not 32 bit }
-             if not(p.nodetype in [nothingn,calln,assignn,breakn,inlinen,continuen,labeln,blockn,
-                                   simplenewn,simpledisposen]) then
+             if not(p.nodetype in [nothingn,calln,assignn,breakn,inlinen,
+                                   continuen,labeln,blockn]) then
                Message(cg_e_illegal_expression);
                Message(cg_e_illegal_expression);
 
 
              { specify that we don't use the value returned by the call }
              { specify that we don't use the value returned by the call }
@@ -1071,7 +1071,7 @@ implementation
       {# Optimize the assembler block by removing all references
       {# Optimize the assembler block by removing all references
          which are via the frame pointer by replacing them with
          which are via the frame pointer by replacing them with
          references via the stack pointer.
          references via the stack pointer.
-         
+
          This is only available to certain cpu targets where
          This is only available to certain cpu targets where
          the frame pointer saving must be done explicitly.
          the frame pointer saving must be done explicitly.
       }
       }
@@ -1178,8 +1178,8 @@ implementation
            following conditions are met:
            following conditions are met:
            - if the are no local variables
            - if the are no local variables
            - no reference to the result variable (refcount<=1)
            - no reference to the result variable (refcount<=1)
-           - result is not stored as parameter 
-           - target processor has optional frame pointer save 
+           - result is not stored as parameter
+           - target processor has optional frame pointer save
              (vm, i386, vm only currently)
              (vm, i386, vm only currently)
          }
          }
          if (po_assembler in aktprocdef.procoptions) and
          if (po_assembler in aktprocdef.procoptions) and
@@ -1213,7 +1213,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.53  2002-04-20 21:32:24  carl
+  Revision 1.54  2002-04-21 19:02:05  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.53  2002/04/20 21:32:24  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants

+ 10 - 1
compiler/symdef.pas

@@ -745,6 +745,8 @@ implementation
         prefix : string;
         prefix : string;
       begin
       begin
         prefix:='';
         prefix:='';
+        if not assigned(st) then
+         internalerror(200204212);
         { sub procedures }
         { sub procedures }
         while (st.symtabletype=localsymtable) do
         while (st.symtabletype=localsymtable) do
          begin
          begin
@@ -5468,7 +5470,14 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.72  2002-04-20 21:32:25  carl
+  Revision 1.73  2002-04-21 19:02:05  peter
+    * removed newn and disposen nodes, the code is now directly
+      inlined from pexpr
+    * -an option that will write the secondpass nodes to the .s file, this
+      requires EXTDEBUG define to actually write the info
+    * fixed various internal errors and crashes due recent code changes
+
+  Revision 1.72  2002/04/20 21:32:25  carl
   + generic FPC_CHECKPOINTER
   + generic FPC_CHECKPOINTER
   + first parameter offset in stack now portable
   + first parameter offset in stack now portable
   * rename some constants
   * rename some constants