mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 02:11:30 +01:00 
			
		
		
		
	* fixed generation of rtti for virtualmethods
This commit is contained in:
		
							parent
							
								
									3dfc2332cb
								
							
						
					
					
						commit
						e417ee0e7f
					
				| @ -86,6 +86,7 @@ interface | |||||||
|         has_virtual_method : boolean; |         has_virtual_method : boolean; | ||||||
|         procedure eachsym(sym : tnamedindexitem); |         procedure eachsym(sym : tnamedindexitem); | ||||||
|         procedure disposevmttree; |         procedure disposevmttree; | ||||||
|  |         procedure writevirtualmethods(List:TAAsmoutput); | ||||||
|       private |       private | ||||||
|         { interface tables } |         { interface tables } | ||||||
|         function  gintfgetvtbllabelname(intfindex: integer): string; |         function  gintfgetvtbllabelname(intfindex: integer): string; | ||||||
| @ -100,19 +101,20 @@ interface | |||||||
|         procedure cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract; |         procedure cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract; | ||||||
|       public |       public | ||||||
|         constructor create(c:tobjectdef); |         constructor create(c:tobjectdef); | ||||||
|  |         destructor destroy;override; | ||||||
|         { generates the message tables for a class } |         { generates the message tables for a class } | ||||||
|         function  genstrmsgtab : tasmlabel; |         function  genstrmsgtab : tasmlabel; | ||||||
|         function  genintmsgtab : tasmlabel; |         function  genintmsgtab : tasmlabel; | ||||||
|         function  genpublishedmethodstable : tasmlabel; |         function  genpublishedmethodstable : tasmlabel; | ||||||
|  |         { generates a VMT entries } | ||||||
|  |         procedure genvmt; | ||||||
| {$ifdef WITHDMT} | {$ifdef WITHDMT} | ||||||
|         { generates a DMT for _class } |         { generates a DMT for _class } | ||||||
|         function  gendmt : tasmlabel; |         function  gendmt : tasmlabel; | ||||||
| {$endif WITHDMT} | {$endif WITHDMT} | ||||||
|         { generates a VMT for _class } |  | ||||||
|         procedure genvmt(list : TAAsmoutput); |  | ||||||
|         { interfaces } |         { interfaces } | ||||||
|         function  genintftable: tasmlabel; |         function  genintftable: tasmlabel; | ||||||
| 
 |         { write the VMT to datasegment } | ||||||
|         procedure writevmt; |         procedure writevmt; | ||||||
|         procedure writeinterfaceids; |         procedure writeinterfaceids; | ||||||
|       end; |       end; | ||||||
| @ -152,6 +154,12 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     destructor tclassheader.destroy; | ||||||
|  |       begin | ||||||
|  |         disposevmttree; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| {************************************** | {************************************** | ||||||
|            Message Tables |            Message Tables | ||||||
| **************************************} | **************************************} | ||||||
| @ -729,7 +737,7 @@ implementation | |||||||
|        end; |        end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.genvmt(list : TAAsmoutput); |     procedure tclassheader.genvmt; | ||||||
| 
 | 
 | ||||||
|       procedure do_genvmt(p : tobjectdef); |       procedure do_genvmt(p : tobjectdef); | ||||||
| 
 | 
 | ||||||
| @ -742,11 +750,6 @@ implementation | |||||||
|            p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym); |            p.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}eachsym); | ||||||
|         end; |         end; | ||||||
| 
 | 
 | ||||||
|       var |  | ||||||
|          symcoll : psymcoll; |  | ||||||
|          procdefcoll : pprocdefcoll; |  | ||||||
|          i : longint; |  | ||||||
| 
 |  | ||||||
|       begin |       begin | ||||||
|          wurzel:=nil; |          wurzel:=nil; | ||||||
|          nextvirtnumber:=0; |          nextvirtnumber:=0; | ||||||
| @ -759,50 +762,6 @@ implementation | |||||||
| 
 | 
 | ||||||
|          if has_virtual_method and not(has_constructor) then |          if has_virtual_method and not(has_constructor) then | ||||||
|             Message1(parser_w_virtual_without_constructor,_class.objname^); |             Message1(parser_w_virtual_without_constructor,_class.objname^); | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|          { generates the VMT } |  | ||||||
| 
 |  | ||||||
|          { walk trough all numbers for virtual methods and search } |  | ||||||
|          { the method                                             } |  | ||||||
|          for i:=0 to nextvirtnumber-1 do |  | ||||||
|            begin |  | ||||||
|               symcoll:=wurzel; |  | ||||||
| 
 |  | ||||||
|               { walk trough all symbols } |  | ||||||
|               while assigned(symcoll) do |  | ||||||
|                 begin |  | ||||||
| 
 |  | ||||||
|                    { walk trough all methods } |  | ||||||
|                    procdefcoll:=symcoll^.data; |  | ||||||
|                    while assigned(procdefcoll) do |  | ||||||
|                      begin |  | ||||||
|                         { writes the addresses to the VMT } |  | ||||||
|                         { but only this which are declared as virtual } |  | ||||||
|                         if procdefcoll^.data.extnumber=i then |  | ||||||
|                           begin |  | ||||||
|                              if (po_virtualmethod in procdefcoll^.data.procoptions) then |  | ||||||
|                                begin |  | ||||||
|                                   { if a method is abstract, then is also the } |  | ||||||
|                                   { class abstract and it's not allow to      } |  | ||||||
|                                   { generates an instance                     } |  | ||||||
|                                   if (po_abstractmethod in procdefcoll^.data.procoptions) then |  | ||||||
|                                     begin |  | ||||||
|                                        include(_class.objectoptions,oo_has_abstract); |  | ||||||
|                                        List.concat(Tai_const_symbol.Createname('FPC_ABSTRACTERROR')); |  | ||||||
|                                     end |  | ||||||
|                                   else |  | ||||||
|                                     begin |  | ||||||
|                                       List.concat(Tai_const_symbol.createname(procdefcoll^.data.mangledname)); |  | ||||||
|                                     end; |  | ||||||
|                                end; |  | ||||||
|                           end; |  | ||||||
|                         procdefcoll:=procdefcoll^.next; |  | ||||||
|                      end; |  | ||||||
|                    symcoll:=symcoll^.next; |  | ||||||
|                 end; |  | ||||||
|            end; |  | ||||||
|          disposevmttree; |  | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -1135,11 +1094,58 @@ implementation | |||||||
|       dataSegment.concat(Tai_string.Create(_class.iidstr^)); |       dataSegment.concat(Tai_string.Create(_class.iidstr^)); | ||||||
|     end; |     end; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     procedure tclassheader.writevirtualmethods(List:TAAsmoutput); | ||||||
|  |       var | ||||||
|  |          symcoll : psymcoll; | ||||||
|  |          procdefcoll : pprocdefcoll; | ||||||
|  |          i : longint; | ||||||
|  |       begin | ||||||
|  |          { walk trough all numbers for virtual methods and search } | ||||||
|  |          { the method                                             } | ||||||
|  |          for i:=0 to nextvirtnumber-1 do | ||||||
|  |            begin | ||||||
|  |               symcoll:=wurzel; | ||||||
|  | 
 | ||||||
|  |               { walk trough all symbols } | ||||||
|  |               while assigned(symcoll) do | ||||||
|  |                 begin | ||||||
|  | 
 | ||||||
|  |                    { walk trough all methods } | ||||||
|  |                    procdefcoll:=symcoll^.data; | ||||||
|  |                    while assigned(procdefcoll) do | ||||||
|  |                      begin | ||||||
|  |                         { writes the addresses to the VMT } | ||||||
|  |                         { but only this which are declared as virtual } | ||||||
|  |                         if procdefcoll^.data.extnumber=i then | ||||||
|  |                           begin | ||||||
|  |                              if (po_virtualmethod in procdefcoll^.data.procoptions) then | ||||||
|  |                                begin | ||||||
|  |                                   { if a method is abstract, then is also the } | ||||||
|  |                                   { class abstract and it's not allow to      } | ||||||
|  |                                   { generates an instance                     } | ||||||
|  |                                   if (po_abstractmethod in procdefcoll^.data.procoptions) then | ||||||
|  |                                     begin | ||||||
|  |                                        include(_class.objectoptions,oo_has_abstract); | ||||||
|  |                                        List.concat(Tai_const_symbol.Createname('FPC_ABSTRACTERROR')); | ||||||
|  |                                     end | ||||||
|  |                                   else | ||||||
|  |                                     begin | ||||||
|  |                                       List.concat(Tai_const_symbol.createname(procdefcoll^.data.mangledname)); | ||||||
|  |                                     end; | ||||||
|  |                                end; | ||||||
|  |                           end; | ||||||
|  |                         procdefcoll:=procdefcoll^.next; | ||||||
|  |                      end; | ||||||
|  |                    symcoll:=symcoll^.next; | ||||||
|  |                 end; | ||||||
|  |            end; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|     { generates the vmt for classes as well as for objects } |     { generates the vmt for classes as well as for objects } | ||||||
|     procedure tclassheader.writevmt; |     procedure tclassheader.writevmt; | ||||||
| 
 | 
 | ||||||
|       var |       var | ||||||
|          vmtlist : taasmoutput; |  | ||||||
|          methodnametable,intmessagetable, |          methodnametable,intmessagetable, | ||||||
|          strmessagetable,classnamelabel, |          strmessagetable,classnamelabel, | ||||||
|          fieldtablelabel : tasmlabel; |          fieldtablelabel : tasmlabel; | ||||||
| @ -1151,9 +1157,6 @@ implementation | |||||||
| {$ifdef WITHDMT} | {$ifdef WITHDMT} | ||||||
|          dmtlabel:=gendmt; |          dmtlabel:=gendmt; | ||||||
| {$endif WITHDMT} | {$endif WITHDMT} | ||||||
|          { this generates the entries } |  | ||||||
|          vmtlist:=TAasmoutput.Create; |  | ||||||
|          genvmt(vmtlist); |  | ||||||
| 
 | 
 | ||||||
|          if (cs_create_smart in aktmoduleswitches) then |          if (cs_create_smart in aktmoduleswitches) then | ||||||
|            dataSegment.concat(Tai_cut.Create); |            dataSegment.concat(Tai_cut.Create); | ||||||
| @ -1258,8 +1261,8 @@ implementation | |||||||
|             else |             else | ||||||
|               dataSegment.concat(Tai_const.Create_32bit(0)); |               dataSegment.concat(Tai_const.Create_32bit(0)); | ||||||
|           end; |           end; | ||||||
|          dataSegment.concatlist(vmtlist); |          { write virtual methods } | ||||||
|          vmtlist.free; |          writevirtualmethods(dataSegment); | ||||||
|          { write the size of the VMT } |          { write the size of the VMT } | ||||||
|          dataSegment.concat(Tai_symbol_end.Createname(_class.vmt_mangledname)); |          dataSegment.concat(Tai_symbol_end.Createname(_class.vmt_mangledname)); | ||||||
|       end; |       end; | ||||||
| @ -1270,7 +1273,10 @@ initialization | |||||||
| end. | end. | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.4  2001-09-19 11:04:42  michael |   Revision 1.5  2001-10-20 17:20:14  peter | ||||||
|  |     * fixed generation of rtti for virtualmethods | ||||||
|  | 
 | ||||||
|  |   Revision 1.4  2001/09/19 11:04:42  michael | ||||||
|   * Smartlinking with interfaces fixed |   * Smartlinking with interfaces fixed | ||||||
|   * Better smartlinking for rtti and init tables |   * Better smartlinking for rtti and init tables | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -477,12 +477,6 @@ implementation | |||||||
|               oldfilepos:=aktfilepos; |               oldfilepos:=aktfilepos; | ||||||
|               aktfilepos:=newtype.fileinfo; |               aktfilepos:=newtype.fileinfo; | ||||||
| 
 | 
 | ||||||
|               { generate rtti info for classes, but not for forward classes } |  | ||||||
|               if (tt.def.deftype=objectdef) and |  | ||||||
|                  (oo_can_have_published in tobjectdef(tt.def).objectoptions) and |  | ||||||
|                  not(oo_is_forward in tobjectdef(tt.def).objectoptions) then |  | ||||||
|                 generate_rtti(newtype); |  | ||||||
| 
 |  | ||||||
|               { generate persistent init/final tables when it's declared in the interface so it can |               { generate persistent init/final tables when it's declared in the interface so it can | ||||||
|                 be reused in other used } |                 be reused in other used } | ||||||
|               if (not current_module.in_implementation) and |               if (not current_module.in_implementation) and | ||||||
| @ -498,6 +492,12 @@ implementation | |||||||
|                  not(oo_is_forward in tobjectdef(tt.def).objectoptions) then |                  not(oo_is_forward in tobjectdef(tt.def).objectoptions) then | ||||||
|                begin |                begin | ||||||
|                  ch:=cclassheader.create(tobjectdef(tt.def)); |                  ch:=cclassheader.create(tobjectdef(tt.def)); | ||||||
|  |                  { generate and check virtual methods, must be done | ||||||
|  |                    before RTTI is written } | ||||||
|  |                  ch.genvmt; | ||||||
|  |                  { generate rtti info if published items are available } | ||||||
|  |                  if (oo_can_have_published in tobjectdef(tt.def).objectoptions) then | ||||||
|  |                    generate_rtti(newtype); | ||||||
|                  if is_interface(tobjectdef(tt.def)) then |                  if is_interface(tobjectdef(tt.def)) then | ||||||
|                    ch.writeinterfaceids; |                    ch.writeinterfaceids; | ||||||
|                  if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then |                  if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then | ||||||
| @ -593,7 +593,10 @@ implementation | |||||||
| end. | end. | ||||||
| { | { | ||||||
|   $Log$ |   $Log$ | ||||||
|   Revision 1.34  2001-09-19 11:06:03  michael |   Revision 1.35  2001-10-20 17:20:13  peter | ||||||
|  |     * fixed generation of rtti for virtualmethods | ||||||
|  | 
 | ||||||
|  |   Revision 1.34  2001/09/19 11:06:03  michael | ||||||
|   * realname updated for some hints |   * realname updated for some hints | ||||||
|   * realname used for consts,labels |   * realname used for consts,labels | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 peter
						peter