mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 03:11:39 +01:00 
			
		
		
		
	* refactor implemented interfaces
git-svn-id: trunk@5134 -
This commit is contained in:
		
							parent
							
								
									72ff9d9f3e
								
							
						
					
					
						commit
						136d3e8d46
					
				| @ -133,10 +133,10 @@ interface | |||||||
|         function  RefAsmSymbol(const s : string) : tasmsymbol; |         function  RefAsmSymbol(const s : string) : tasmsymbol; | ||||||
|         function  getasmsymbol(const s : string) : tasmsymbol; |         function  getasmsymbol(const s : string) : tasmsymbol; | ||||||
|         { create new assembler label } |         { create new assembler label } | ||||||
|         procedure getlabel(var l : tasmlabel;alt:tasmlabeltype); |         procedure getlabel(out l : tasmlabel;alt:tasmlabeltype); | ||||||
|         procedure getjumplabel(var l : tasmlabel); |         procedure getjumplabel(out l : tasmlabel); | ||||||
|         procedure getaddrlabel(var l : tasmlabel); |         procedure getaddrlabel(out l : tasmlabel); | ||||||
|         procedure getdatalabel(var l : tasmlabel); |         procedure getdatalabel(out l : tasmlabel); | ||||||
|         { generate an alternative (duplicate) symbol } |         { generate an alternative (duplicate) symbol } | ||||||
|         procedure GenerateAltSymbol(p:tasmsymbol); |         procedure GenerateAltSymbol(p:tasmsymbol); | ||||||
|         procedure ResetAltSymbols; |         procedure ResetAltSymbols; | ||||||
| @ -386,7 +386,7 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure TAsmData.getlabel(var l : tasmlabel;alt:tasmlabeltype); |     procedure TAsmData.getlabel(out l : tasmlabel;alt:tasmlabeltype); | ||||||
|       begin |       begin | ||||||
|         l:=tasmlabel.createlocal(FNextLabelNr[alt],alt); |         l:=tasmlabel.createlocal(FNextLabelNr[alt],alt); | ||||||
|         inc(FNextLabelNr[alt]); |         inc(FNextLabelNr[alt]); | ||||||
| @ -394,7 +394,7 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure TAsmData.getjumplabel(var l : tasmlabel); |     procedure TAsmData.getjumplabel(out l : tasmlabel); | ||||||
|       begin |       begin | ||||||
|         l:=tasmlabel.createlocal(FNextLabelNr[alt_jump],alt_jump); |         l:=tasmlabel.createlocal(FNextLabelNr[alt_jump],alt_jump); | ||||||
|         inc(FNextLabelNr[alt_jump]); |         inc(FNextLabelNr[alt_jump]); | ||||||
| @ -402,7 +402,7 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure TAsmData.getdatalabel(var l : tasmlabel); |     procedure TAsmData.getdatalabel(out l : tasmlabel); | ||||||
|       begin |       begin | ||||||
|         l:=tasmlabel.createglobal(name,FNextLabelNr[alt_data],alt_data); |         l:=tasmlabel.createglobal(name,FNextLabelNr[alt_data],alt_data); | ||||||
|         inc(FNextLabelNr[alt_data]); |         inc(FNextLabelNr[alt_data]); | ||||||
| @ -410,7 +410,7 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure TAsmData.getaddrlabel(var l : tasmlabel); |     procedure TAsmData.getaddrlabel(out l : tasmlabel); | ||||||
|       begin |       begin | ||||||
|         l:=tasmlabel.createlocal(FNextLabelNr[alt_addr],alt_addr); |         l:=tasmlabel.createlocal(FNextLabelNr[alt_addr],alt_addr); | ||||||
|         inc(FNextLabelNr[alt_addr]); |         inc(FNextLabelNr[alt_addr]); | ||||||
|  | |||||||
| @ -2658,11 +2658,11 @@ end; | |||||||
|         end; |         end; | ||||||
| 
 | 
 | ||||||
|         { add implemented interfaces } |         { add implemented interfaces } | ||||||
|         if assigned(def.implementedinterfaces) then |         if assigned(def.ImplementedInterfaces) then | ||||||
|           for n := 1 to def.implementedinterfaces.count do |           for n := 0 to def.ImplementedInterfaces.count-1 do | ||||||
|             begin |             begin | ||||||
|               append_entry(DW_TAG_inheritance,false,[]); |               append_entry(DW_TAG_inheritance,false,[]); | ||||||
|               append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.implementedinterfaces.interfaces(n))); |               append_labelentry_ref(DW_AT_type,def_dwarf_lab(TImplementedInterface(def.ImplementedInterfaces[n]).IntfDef)); | ||||||
|               finish_entry; |               finish_entry; | ||||||
|             end; |             end; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -166,7 +166,7 @@ implementation | |||||||
|          subeq,eq : tequaltype; |          subeq,eq : tequaltype; | ||||||
|          hd1,hd2 : tdef; |          hd1,hd2 : tdef; | ||||||
|          hct : tconverttype; |          hct : tconverttype; | ||||||
|          hd3 : tobjectdef; |          hobjdef : tobjectdef; | ||||||
|          hpd : tprocdef; |          hpd : tprocdef; | ||||||
|       begin |       begin | ||||||
|          eq:=te_incompatible; |          eq:=te_incompatible; | ||||||
| @ -1150,20 +1150,20 @@ implementation | |||||||
|                    { classes can be assigned to interfaces } |                    { classes can be assigned to interfaces } | ||||||
|                    else if is_interface(def_to) and |                    else if is_interface(def_to) and | ||||||
|                            is_class(def_from) and |                            is_class(def_from) and | ||||||
|                      assigned(tobjectdef(def_from).implementedinterfaces) then |                            assigned(tobjectdef(def_from).ImplementedInterfaces) then | ||||||
|                      begin |                      begin | ||||||
|                         { we've to search in parent classes as well } |                         { we've to search in parent classes as well } | ||||||
|                         hd3:=tobjectdef(def_from); |                         hobjdef:=tobjectdef(def_from); | ||||||
|                         while assigned(hd3) do |                         while assigned(hobjdef) do | ||||||
|                           begin |                           begin | ||||||
|                              if hd3.implementedinterfaces.searchintf(def_to)<>-1 then |                              if hobjdef.find_implemented_interface(tobjectdef(def_to))<>nil then | ||||||
|                                begin |                                begin | ||||||
|                                   doconv:=tc_class_2_intf; |                                   doconv:=tc_class_2_intf; | ||||||
|                                   { don't prefer this over objectdef->objectdef } |                                   { don't prefer this over objectdef->objectdef } | ||||||
|                                   eq:=te_convert_l2; |                                   eq:=te_convert_l2; | ||||||
|                                   break; |                                   break; | ||||||
|                                end; |                                end; | ||||||
|                              hd3:=hd3.childof; |                              hobjdef:=hobjdef.childof; | ||||||
|                           end; |                           end; | ||||||
|                      end |                      end | ||||||
|                    { Interface 2 GUID handling } |                    { Interface 2 GUID handling } | ||||||
|  | |||||||
| @ -448,6 +448,7 @@ interface | |||||||
|       var |       var | ||||||
|          l1 : tasmlabel; |          l1 : tasmlabel; | ||||||
|          hd : tobjectdef; |          hd : tobjectdef; | ||||||
|  |          ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|          location_reset(location,LOC_REGISTER,OS_ADDR); |          location_reset(location,LOC_REGISTER,OS_ADDR); | ||||||
|          case left.location.loc of |          case left.location.loc of | ||||||
| @ -473,11 +474,10 @@ interface | |||||||
|          hd:=tobjectdef(left.resultdef); |          hd:=tobjectdef(left.resultdef); | ||||||
|          while assigned(hd) do |          while assigned(hd) do | ||||||
|            begin |            begin | ||||||
|               if hd.implementedinterfaces.searchintf(resultdef)<>-1 then |              ImplIntf:=hd.find_implemented_interface(tobjectdef(resultdef)); | ||||||
|  |              if assigned(ImplIntf) then | ||||||
|                begin |                begin | ||||||
|                    cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR, |                  cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,ImplIntf.ioffset,location.register); | ||||||
|                      hd.implementedinterfaces.ioffsets( |  | ||||||
|                        hd.implementedinterfaces.searchintf(resultdef)),location.register); |  | ||||||
|                  break; |                  break; | ||||||
|                end; |                end; | ||||||
|              hd:=hd.childof; |              hd:=hd.childof; | ||||||
|  | |||||||
| @ -2722,25 +2722,26 @@ implementation | |||||||
| 
 | 
 | ||||||
|     procedure gen_intf_wrapper(list:TAsmList;_class:tobjectdef); |     procedure gen_intf_wrapper(list:TAsmList;_class:tobjectdef); | ||||||
|       var |       var | ||||||
|         i,j, |         i,j  : longint; | ||||||
|         proccount : longint; |  | ||||||
|         tmps : string; |         tmps : string; | ||||||
|  |         pd   : TProcdef; | ||||||
|  |         ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|         for i:=1 to _class.implementedinterfaces.count do |         for i:=0 to _class.ImplementedInterfaces.count-1 do | ||||||
|           begin |           begin | ||||||
|             { only if implemented by this class } |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|             if _class.implementedinterfaces.implindex(i)=i then |             if (ImplIntf=ImplIntf.VtblImplIntf) and | ||||||
|  |                assigned(ImplIntf.ProcDefs) then | ||||||
|               begin |               begin | ||||||
|                 proccount:=_class.implementedinterfaces.implproccount(i); |                 for j:=0 to ImplIntf.ProcDefs.Count-1 do | ||||||
|                 for j:=1 to proccount do |  | ||||||
|                   begin |                   begin | ||||||
|  |                     pd:=TProcdef(ImplIntf.ProcDefs[j]); | ||||||
|                     tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+ |                     tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+ | ||||||
|                       _class.implementedinterfaces.interfaces(i).objname^+'_$_'+ |                       ImplIntf.IntfDef.objname^+'_$_'+tostr(j)+'_$_'+pd.mangledname); | ||||||
|                       tostr(j)+'_$_'+_class.implementedinterfaces.implprocs(i,j).mangledname); |  | ||||||
|                     { create wrapper code } |                     { create wrapper code } | ||||||
|                     new_section(list,sec_code,lower(tmps),0); |                     new_section(list,sec_code,tmps,0); | ||||||
|                     cg.init_register_allocators; |                     cg.init_register_allocators; | ||||||
|                     cg.g_intf_wrapper(list,_class.implementedinterfaces.implprocs(i,j),tmps,_class.implementedinterfaces.ioffsets(i)); |                     cg.g_intf_wrapper(list,pd,tmps,ImplIntf.ioffset); | ||||||
|                     cg.done_register_allocators; |                     cg.done_register_allocators; | ||||||
|                   end; |                   end; | ||||||
|               end; |               end; | ||||||
|  | |||||||
| @ -2766,9 +2766,8 @@ implementation | |||||||
|             { left is a class } |             { left is a class } | ||||||
|             if is_class(left.resultdef) then |             if is_class(left.resultdef) then | ||||||
|              begin |              begin | ||||||
|                { the operands must be related } |                { the class must implement the interface } | ||||||
|                if not(assigned(tobjectdef(left.resultdef).implementedinterfaces) and |                if tobjectdef(left.resultdef).find_implemented_interface(tobjectdef(right.resultdef))=nil then | ||||||
|                       (tobjectdef(left.resultdef).implementedinterfaces.searchintf(right.resultdef)<>-1)) then |  | ||||||
|                  CGMessage2(type_e_classes_not_related, |                  CGMessage2(type_e_classes_not_related, | ||||||
|                     FullTypeName(left.resultdef,right.resultdef), |                     FullTypeName(left.resultdef,right.resultdef), | ||||||
|                     FullTypeName(right.resultdef,left.resultdef)) |                     FullTypeName(right.resultdef,left.resultdef)) | ||||||
|  | |||||||
| @ -95,14 +95,14 @@ interface | |||||||
|         procedure writevirtualmethods(List:TAsmList); |         procedure writevirtualmethods(List:TAsmList); | ||||||
|       private |       private | ||||||
|         { interface tables } |         { interface tables } | ||||||
|         function  gintfgetvtbllabelname(intfindex: integer): string; |         function  intf_get_vtbl_name(AImplIntf:TImplementedInterface): string; | ||||||
|         procedure gintfcreatevtbl(intfindex: integer; rawdata: TAsmList); |         procedure intf_create_vtbl(rawdata: TAsmList;AImplIntf:TImplementedInterface); | ||||||
|         procedure gintfgenentry(intfindex, contintfindex: integer; rawdata: TAsmList); |         procedure intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface); | ||||||
|         procedure gintfoptimizevtbls; |         procedure intf_optimize_vtbls; | ||||||
|         procedure gintfwritedata; |         procedure intf_write_data; | ||||||
|         function  gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef; |         function  intf_search_procdef_by_name(proc: tprocdef;const name: string): tprocdef; | ||||||
|         procedure gintfdoonintf(intf: tobjectdef; intfindex: longint); |         procedure intf_get_procdefs(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); | ||||||
|         procedure gintfwalkdowninterface(intf: tobjectdef; intfindex: longint); |         procedure intf_get_procdefs_recursive(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); | ||||||
|       public |       public | ||||||
|         constructor create(c:tobjectdef); |         constructor create(c:tobjectdef); | ||||||
|         destructor destroy;override; |         destructor destroy;override; | ||||||
| @ -129,7 +129,7 @@ implementation | |||||||
|     uses |     uses | ||||||
|        SysUtils, |        SysUtils, | ||||||
|        globals,verbose,systems, |        globals,verbose,systems, | ||||||
|        symtable,symconst,symtype,defcmp,defutil, |        symtable,symconst,symtype,defcmp, | ||||||
|        dbgbase |        dbgbase | ||||||
|        ; |        ; | ||||||
| 
 | 
 | ||||||
| @ -256,7 +256,7 @@ implementation | |||||||
|     procedure tclassheader.writenames(p : pprocdeftree); |     procedure tclassheader.writenames(p : pprocdeftree); | ||||||
|       var |       var | ||||||
|         ca : pchar; |         ca : pchar; | ||||||
|         len : longint; |         len : byte; | ||||||
|       begin |       begin | ||||||
|          current_asmdata.getdatalabel(p^.nl); |          current_asmdata.getdatalabel(p^.nl); | ||||||
|          if assigned(p^.l) then |          if assigned(p^.l) then | ||||||
| @ -290,7 +290,6 @@ implementation | |||||||
| 
 | 
 | ||||||
|     function tclassheader.genstrmsgtab : tasmlabel; |     function tclassheader.genstrmsgtab : tasmlabel; | ||||||
|       var |       var | ||||||
|          r : tasmlabel; |  | ||||||
|          count : aint; |          count : aint; | ||||||
|       begin |       begin | ||||||
|          root:=nil; |          root:=nil; | ||||||
| @ -303,10 +302,9 @@ implementation | |||||||
|            writenames(root); |            writenames(root); | ||||||
| 
 | 
 | ||||||
|          { now start writing of the message string table } |          { now start writing of the message string table } | ||||||
|          current_asmdata.getdatalabel(r); |          current_asmdata.getdatalabel(result); | ||||||
|          current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(aint)))); |          current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(aint)))); | ||||||
|          current_asmdata.asmlists[al_globals].concat(Tai_label.Create(r)); |          current_asmdata.asmlists[al_globals].concat(Tai_label.Create(result)); | ||||||
|          genstrmsgtab:=r; |  | ||||||
|          current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(count)); |          current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(count)); | ||||||
|          if assigned(root) then |          if assigned(root) then | ||||||
|            begin |            begin | ||||||
| @ -859,60 +857,58 @@ implementation | |||||||
|            Interface tables |            Interface tables | ||||||
| **************************************} | **************************************} | ||||||
| 
 | 
 | ||||||
|     function  tclassheader.gintfgetvtbllabelname(intfindex: integer): string; |     function  tclassheader.intf_get_vtbl_name(AImplIntf:TImplementedInterface): string; | ||||||
|       begin |       begin | ||||||
|         gintfgetvtbllabelname:=make_mangledname('VTBL',_class.owner,_class.objname^+ |         result:=make_mangledname('VTBL',_class.owner,_class.objname^+'_$_'+AImplIntf.IntfDef.objname^); | ||||||
|                                '_$_'+_class.implementedinterfaces.interfaces(intfindex).objname^); |  | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfcreatevtbl(intfindex: integer; rawdata: TAsmList); |     procedure tclassheader.intf_create_vtbl(rawdata: TAsmList;AImplIntf:TImplementedInterface); | ||||||
|       var |       var | ||||||
|         implintf: timplementedinterfaces; |         pd : tprocdef; | ||||||
|         curintf: tobjectdef; |         vtblstr, | ||||||
|         proccount: integer; |         hs : string; | ||||||
|         tmps: string; |         i  : longint; | ||||||
|         i: longint; |  | ||||||
|       begin |       begin | ||||||
|         implintf:=_class.implementedinterfaces; |         vtblstr:=intf_get_vtbl_name(AImplIntf); | ||||||
|         curintf:=implintf.interfaces(intfindex); |         section_symbol_start(rawdata,vtblstr,AT_DATA,true,sec_data,const_align(sizeof(aint))); | ||||||
| 
 |         if assigned(AImplIntf.procdefs) then | ||||||
|         section_symbol_start(rawdata,gintfgetvtbllabelname(intfindex),AT_DATA,true,sec_data,const_align(sizeof(aint))); |  | ||||||
|         proccount:=implintf.implproccount(intfindex); |  | ||||||
|         for i:=1 to proccount do |  | ||||||
|           begin |           begin | ||||||
|             tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+curintf.objname^+'_$_'+ |             for i:=0 to AImplIntf.procdefs.count-1 do | ||||||
|               tostr(i)+'_$_'+ |               begin | ||||||
|               implintf.implprocs(intfindex,i).mangledname); |                 pd:=tprocdef(AImplIntf.procdefs[i]); | ||||||
|  |                 hs:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+AImplIntf.IntfDef.objname^+'_$_'+ | ||||||
|  |                                      tostr(i)+'_$_'+pd.mangledname); | ||||||
|                 { create reference } |                 { create reference } | ||||||
|             rawdata.concat(Tai_const.Createname(tmps,0)); |                 rawdata.concat(Tai_const.Createname(hs,0)); | ||||||
|               end; |               end; | ||||||
|         section_symbol_end(rawdata,gintfgetvtbllabelname(intfindex)); |            end; | ||||||
|  |         section_symbol_end(rawdata,vtblstr); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfgenentry(intfindex, contintfindex: integer; rawdata: TAsmList); |     procedure tclassheader.intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface); | ||||||
|       var |       var | ||||||
|         implintf: timplementedinterfaces; |         iidlabel, | ||||||
|         curintf: tobjectdef; |         guidlabel : tasmlabel; | ||||||
|         tmplabel: tasmlabel; |  | ||||||
|         i: longint; |         i: longint; | ||||||
|       begin |       begin | ||||||
|         implintf:=_class.implementedinterfaces; |  | ||||||
|         curintf:=implintf.interfaces(intfindex); |  | ||||||
|         { GUID } |         { GUID } | ||||||
|         if curintf.objecttype in [odt_interfacecom] then |         if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then | ||||||
|           begin |           begin | ||||||
|             { label for GUID } |             { label for GUID } | ||||||
|             current_asmdata.getdatalabel(tmplabel); |             current_asmdata.getdatalabel(guidlabel); | ||||||
|             rawdata.concat(cai_align.create(const_align(sizeof(aint)))); |             rawdata.concat(cai_align.create(const_align(sizeof(aint)))); | ||||||
|             rawdata.concat(Tai_label.Create(tmplabel)); |             rawdata.concat(Tai_label.Create(guidlabel)); | ||||||
|             rawdata.concat(Tai_const.Create_32bit(longint(curintf.iidguid^.D1))); |             with AImplIntf.IntfDef.iidguid^ do | ||||||
|             rawdata.concat(Tai_const.Create_16bit(curintf.iidguid^.D2)); |               begin | ||||||
|             rawdata.concat(Tai_const.Create_16bit(curintf.iidguid^.D3)); |                 rawdata.concat(Tai_const.Create_32bit(longint(D1))); | ||||||
|             for i:=Low(curintf.iidguid^.D4) to High(curintf.iidguid^.D4) do |                 rawdata.concat(Tai_const.Create_16bit(D2)); | ||||||
|               rawdata.concat(Tai_const.Create_8bit(curintf.iidguid^.D4[i])); |                 rawdata.concat(Tai_const.Create_16bit(D3)); | ||||||
|             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(tmplabel)); |                 for i:=Low(D4) to High(D4) do | ||||||
|  |                   rawdata.concat(Tai_const.Create_8bit(D4[i])); | ||||||
|  |               end; | ||||||
|  |             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(guidlabel)); | ||||||
|           end |           end | ||||||
|         else |         else | ||||||
|           begin |           begin | ||||||
| @ -920,73 +916,77 @@ implementation | |||||||
|             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); |             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); | ||||||
|           end; |           end; | ||||||
|         { VTable } |         { VTable } | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(gintfgetvtbllabelname(contintfindex),0)); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0)); | ||||||
|         { IOffset field } |         { IOffset field } | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(implintf.ioffsets(contintfindex))); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(AImplIntf.VtblImplIntf.ioffset)); | ||||||
|         { IIDStr } |         { IIDStr } | ||||||
|         current_asmdata.getdatalabel(tmplabel); |         current_asmdata.getdatalabel(iidlabel); | ||||||
|         rawdata.concat(cai_align.create(const_align(sizeof(aint)))); |         rawdata.concat(cai_align.create(const_align(sizeof(aint)))); | ||||||
|         rawdata.concat(Tai_label.Create(tmplabel)); |         rawdata.concat(Tai_label.Create(iidlabel)); | ||||||
|         rawdata.concat(Tai_const.Create_8bit(length(curintf.iidstr^))); |         rawdata.concat(Tai_const.Create_8bit(length(AImplIntf.IntfDef.iidstr^))); | ||||||
|         if curintf.objecttype=odt_interfacecom then |         if AImplIntf.IntfDef.objecttype=odt_interfacecom then | ||||||
|           rawdata.concat(Tai_string.Create(upper(curintf.iidstr^))) |           rawdata.concat(Tai_string.Create(upper(AImplIntf.IntfDef.iidstr^))) | ||||||
|         else |         else | ||||||
|           rawdata.concat(Tai_string.Create(curintf.iidstr^)); |           rawdata.concat(Tai_string.Create(AImplIntf.IntfDef.iidstr^)); | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(tmplabel)); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(iidlabel)); | ||||||
|         { EntryType } |         { EntryType } | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(integer(curintf.iitype))); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(aint(AImplIntf.IntfDef.iitype))); | ||||||
|         { EntryOffset } |         { EntryOffset } | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(integer(curintf.iioffset))); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(aint(AImplIntf.IntfDef.iioffset))); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfoptimizevtbls; |     procedure tclassheader.intf_optimize_vtbls; | ||||||
|       type |       type | ||||||
|         tcompintfentry = record |         tcompintfentry = record | ||||||
|           weight: longint; |           weight: longint; | ||||||
|           compintf: longint; |           compintf: longint; | ||||||
|         end; |         end; | ||||||
|         { Max 1000 interface in the class header interfaces it's enough imho } |         { Max 1000 interface in the class header interfaces it's enough imho } | ||||||
|         tcompintfs = array[1..1000] of tcompintfentry; |         tcompintfs = array[0..1000] of tcompintfentry; | ||||||
|         pcompintfs = ^tcompintfs; |         pcompintfs = ^tcompintfs; | ||||||
|         tequals    = array[1..1000] of longint; |         tequals    = array[0..1000] of longint; | ||||||
|         pequals    = ^tequals; |         pequals    = ^tequals; | ||||||
|         timpls    = array[1..1000] of longint; |         timpls    = array[0..1000] of longint; | ||||||
|         pimpls    = ^timpls; |         pimpls    = ^timpls; | ||||||
|       var |       var | ||||||
|         max: longint; |  | ||||||
|         equals: pequals; |         equals: pequals; | ||||||
|         compats: pcompintfs; |         compats: pcompintfs; | ||||||
|         impls: pimpls; |         impls: pimpls; | ||||||
|  |         ImplIntfCount, | ||||||
|         w,i,j,k: longint; |         w,i,j,k: longint; | ||||||
|  |         ImplIntfI, | ||||||
|  |         ImplIntfJ  : TImplementedInterface; | ||||||
|         cij: boolean; |         cij: boolean; | ||||||
|         cji: boolean; |         cji: boolean; | ||||||
|       begin |       begin | ||||||
|         max:=_class.implementedinterfaces.count; |         ImplIntfCount:=_class.ImplementedInterfaces.count; | ||||||
|         if max>High(tequals) then |         if ImplIntfCount>=High(tequals) then | ||||||
|           Internalerror(200006135); |           Internalerror(200006135); | ||||||
|         getmem(compats,sizeof(tcompintfentry)*max); |         getmem(compats,sizeof(tcompintfentry)*ImplIntfCount); | ||||||
|         getmem(equals,sizeof(longint)*max); |         getmem(equals,sizeof(longint)*ImplIntfCount); | ||||||
|         getmem(impls,sizeof(longint)*max); |         getmem(impls,sizeof(longint)*ImplIntfCount); | ||||||
|         fillchar(compats^,sizeof(tcompintfentry)*max,0); |         filldword(compats^,(sizeof(tcompintfentry) div sizeof(dword))*ImplIntfCount,dword(-1)); | ||||||
|         fillchar(equals^,sizeof(longint)*max,0); |         filldword(equals^,ImplIntfCount,dword(-1)); | ||||||
|         fillchar(impls^,sizeof(longint)*max,0); |         filldword(impls^,ImplIntfCount,dword(-1)); | ||||||
|         { ismergepossible is a containing relation |         { ismergepossible is a containing relation | ||||||
|           meaning of ismergepossible(a,b,w) = |           meaning of ismergepossible(a,b,w) = | ||||||
|           if implementorfunction map of a is contained implementorfunction map of b |           if implementorfunction map of a is contained implementorfunction map of b | ||||||
|           imp(a,b) and imp(b,c) => imp(a,c) ; imp(a,b) and imp(b,a) => a == b |           imp(a,b) and imp(b,c) => imp(a,c) ; imp(a,b) and imp(b,a) => a == b | ||||||
|         } |         } | ||||||
|         { the order is very important for correct allocation } |         { the order is very important for correct allocation } | ||||||
|         for i:=1 to max do |         for i:=0 to ImplIntfCount-1 do | ||||||
|           begin |           begin | ||||||
|             for j:=i+1 to max do |             for j:=i+1 to ImplIntfCount-1 do | ||||||
|               begin |               begin | ||||||
|                 cij:=_class.implementedinterfaces.isimplmergepossible(i,j,w); |                 ImplIntfI:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|                 cji:=_class.implementedinterfaces.isimplmergepossible(j,i,w); |                 ImplIntfJ:=TImplementedInterface(_class.ImplementedInterfaces[j]); | ||||||
|  |                 cij:=ImplIntfI.IsImplMergePossible(ImplIntfJ,w); | ||||||
|  |                 cji:=ImplIntfJ.IsImplMergePossible(ImplIntfI,w); | ||||||
|                 if cij and cji then { i equal j } |                 if cij and cji then { i equal j } | ||||||
|                   begin |                   begin | ||||||
|                     { get minimum index of equal } |                     { get minimum index of equal } | ||||||
|                     if equals^[j]=0 then |                     if equals^[j]=-1 then | ||||||
|                       equals^[j]:=i; |                       equals^[j]:=i; | ||||||
|                   end |                   end | ||||||
|                 else if cij then |                 else if cij then | ||||||
| @ -1010,7 +1010,7 @@ implementation | |||||||
|               end; |               end; | ||||||
|           end; |           end; | ||||||
|         { Reset, no replacements by default } |         { Reset, no replacements by default } | ||||||
|         for i:=1 to max do |         for i:=0 to ImplIntfCount-1 do | ||||||
|           impls^[i]:=i; |           impls^[i]:=i; | ||||||
|         { Replace vtbls when equal or compat, repeat |         { Replace vtbls when equal or compat, repeat | ||||||
|           until there are no replacements possible anymore. This is |           until there are no replacements possible anymore. This is | ||||||
| @ -1020,64 +1020,70 @@ implementation | |||||||
|         } |         } | ||||||
|         repeat |         repeat | ||||||
|           k:=0; |           k:=0; | ||||||
|           for i:=1 to max do |           for i:=0 to ImplIntfCount-1 do | ||||||
|             begin |             begin | ||||||
|               if compats^[impls^[i]].compintf<>0 then |               if compats^[impls^[i]].compintf<>-1 then | ||||||
|                 impls^[i]:=compats^[impls^[i]].compintf |                 impls^[i]:=compats^[impls^[i]].compintf | ||||||
|               else if equals^[impls^[i]]<>0 then |               else if equals^[impls^[i]]<>-1 then | ||||||
|                 impls^[i]:=equals^[impls^[i]] |                 impls^[i]:=equals^[impls^[i]] | ||||||
|               else |               else | ||||||
|                 inc(k); |                 inc(k); | ||||||
|             end; |             end; | ||||||
|         until k=max; |         until k=ImplIntfCount; | ||||||
|         { Update the implindex } |         { Update the VtblImplIntf } | ||||||
|         for i:=1 to max do |         for i:=0 to ImplIntfCount-1 do | ||||||
|           _class.implementedinterfaces.setimplindex(i,impls^[i]); |           begin | ||||||
|  |             ImplIntfI:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|  |             ImplIntfI.VtblImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[impls^[i]]); | ||||||
|  |           end; | ||||||
|         freemem(compats); |         freemem(compats); | ||||||
|         freemem(equals); |         freemem(equals); | ||||||
|         freemem(impls); |         freemem(impls); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfwritedata; |     procedure tclassheader.intf_write_data; | ||||||
|       var |       var | ||||||
|         rawdata: TAsmList; |         rawdata  : TAsmList; | ||||||
|         max,i,j : smallint; |         i        : longint; | ||||||
|  |         ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|         max:=_class.implementedinterfaces.count; |  | ||||||
| 
 |  | ||||||
|         rawdata:=TAsmList.Create; |         rawdata:=TAsmList.Create; | ||||||
|         { Two pass, one for allocation and vtbl creation } |         { Two pass, one for allocation and vtbl creation } | ||||||
|         for i:=1 to max do |         for i:=0 to _class.ImplementedInterfaces.count-1 do | ||||||
|           begin |           begin | ||||||
|             if _class.implementedinterfaces.implindex(i)=i then { if implement itself } |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|  |             { if it implements itself } | ||||||
|  |             if ImplIntf.VtblImplIntf=ImplIntf then | ||||||
|               begin |               begin | ||||||
|                 { allocate a pointer in the object memory } |                 { allocate a pointer in the object memory } | ||||||
|                 with tobjectsymtable(_class.symtable) do |                 with tobjectsymtable(_class.symtable) do | ||||||
|                   begin |                   begin | ||||||
|                     datasize:=align(datasize,sizeof(aint)); |                     datasize:=align(datasize,sizeof(aint)); | ||||||
|                     _class.implementedinterfaces.setioffsets(i,datasize); |                     ImplIntf.Ioffset:=datasize; | ||||||
|                     inc(datasize,sizeof(aint)); |                     inc(datasize,sizeof(aint)); | ||||||
|                   end; |                   end; | ||||||
|                 { write vtbl } |                 { write vtbl } | ||||||
|                 gintfcreatevtbl(i,rawdata); |                 intf_create_vtbl(rawdata,ImplIntf); | ||||||
|               end; |               end; | ||||||
|           end; |           end; | ||||||
|         { second pass: for fill interfacetable and remained ioffsets } |         { second pass: for fill interfacetable and remained ioffsets } | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(max)); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Create_aint(_class.ImplementedInterfaces.count)); | ||||||
|         for i:=1 to max do |         for i:=0 to _class.ImplementedInterfaces.count-1 do | ||||||
|           begin |           begin | ||||||
|             j:=_class.implementedinterfaces.implindex(i); |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|             if j<>i then |             { Update ioffset of current interface with the ioffset from | ||||||
|               _class.implementedinterfaces.setioffsets(i,_class.implementedinterfaces.ioffsets(j)); |               the interface that is reused to implements this interface } | ||||||
|             gintfgenentry(i,j,rawdata); |             if ImplIntf.VtblImplIntf<>ImplIntf then | ||||||
|  |               ImplIntf.Ioffset:=ImplIntf.VtblImplIntf.Ioffset; | ||||||
|  |             intf_gen_intf_ref(rawdata,ImplIntf); | ||||||
|           end; |           end; | ||||||
|         current_asmdata.asmlists[al_globals].concatlist(rawdata); |         current_asmdata.asmlists[al_globals].concatlist(rawdata); | ||||||
|         rawdata.free; |         rawdata.free; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     function tclassheader.gintfgetcprocdef(proc: tprocdef;const name: string): tprocdef; |     function tclassheader.intf_search_procdef_by_name(proc: tprocdef;const name: string): tprocdef; | ||||||
|       const |       const | ||||||
|         po_comp = [po_classmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint, |         po_comp = [po_classmethod,po_staticmethod,po_interrupt,po_iocheck,po_msgstr,po_msgint, | ||||||
|                    po_exports,po_varargs,po_explicitparaloc,po_nostackframe]; |                    po_exports,po_varargs,po_explicitparaloc,po_nostackframe]; | ||||||
| @ -1086,7 +1092,7 @@ implementation | |||||||
|         implprocdef : Tprocdef; |         implprocdef : Tprocdef; | ||||||
|         i: cardinal; |         i: cardinal; | ||||||
|       begin |       begin | ||||||
|         gintfgetcprocdef:=nil; |         result:=nil; | ||||||
| 
 | 
 | ||||||
|         sym:=tsym(search_class_member(_class,name)); |         sym:=tsym(search_class_member(_class,name)); | ||||||
|         if assigned(sym) and |         if assigned(sym) and | ||||||
| @ -1108,7 +1114,7 @@ implementation | |||||||
|                    (proc.proctypeoption=implprocdef.proctypeoption) and |                    (proc.proctypeoption=implprocdef.proctypeoption) and | ||||||
|                    ((proc.procoptions*po_comp)=((implprocdef.procoptions+[po_virtualmethod])*po_comp)) then |                    ((proc.procoptions*po_comp)=((implprocdef.procoptions+[po_virtualmethod])*po_comp)) then | ||||||
|                   begin |                   begin | ||||||
|                     gintfgetcprocdef:=implprocdef; |                     result:=implprocdef; | ||||||
|                     exit; |                     exit; | ||||||
|                   end; |                   end; | ||||||
|               end; |               end; | ||||||
| @ -1116,35 +1122,35 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfdoonintf(intf: tobjectdef; intfindex: longint); |     procedure tclassheader.intf_get_procdefs(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); | ||||||
|       var |       var | ||||||
|         def: tdef; |         def: tdef; | ||||||
|         hs, |         hs, | ||||||
|         prefix, |         prefix, | ||||||
|         mappedname: string; |         mappedname: string; | ||||||
|         nextexist: pointer; |  | ||||||
|         implprocdef: tprocdef; |         implprocdef: tprocdef; | ||||||
|       begin |       begin | ||||||
|         prefix:=_class.implementedinterfaces.interfaces(intfindex).symtable.name^+'.'; |         prefix:=ImplIntf.IntfDef.symtable.name^+'.'; | ||||||
|         def:=tdef(intf.symtable.defindex.first); |         def:=tdef(IntfDef.symtable.defindex.first); | ||||||
|         while assigned(def) do |         while assigned(def) do | ||||||
|           begin |           begin | ||||||
|             if def.deftype=procdef then |             if def.deftype=procdef then | ||||||
|               begin |               begin | ||||||
|  |                 { Find implementing procdef | ||||||
|  |                    1. Check for mapped name | ||||||
|  |                    2. Use symbol name } | ||||||
|                 implprocdef:=nil; |                 implprocdef:=nil; | ||||||
|                 nextexist:=nil; |  | ||||||
|                 repeat |  | ||||||
|                 hs:=prefix+tprocdef(def).procsym.name; |                 hs:=prefix+tprocdef(def).procsym.name; | ||||||
|                   mappedname:=_class.implementedinterfaces.getmappings(intfindex,hs,nextexist); |                 mappedname:=ImplIntf.GetMapping(hs); | ||||||
|                 if mappedname<>'' then |                 if mappedname<>'' then | ||||||
|                     implprocdef:=gintfgetcprocdef(tprocdef(def),mappedname); |                   implprocdef:=intf_search_procdef_by_name(tprocdef(def),mappedname); | ||||||
|                 until assigned(implprocdef) or not assigned(nextexist); |  | ||||||
|                 if not assigned(implprocdef) then |                 if not assigned(implprocdef) then | ||||||
|                   implprocdef:=gintfgetcprocdef(tprocdef(def),tprocdef(def).procsym.name); |                   implprocdef:=intf_search_procdef_by_name(tprocdef(def),tprocdef(def).procsym.name); | ||||||
|  |                 { Add procdef to the implemented interface } | ||||||
|                 if assigned(implprocdef) then |                 if assigned(implprocdef) then | ||||||
|                   _class.implementedinterfaces.addimplproc(intfindex,implprocdef) |                   ImplIntf.AddImplProc(implprocdef) | ||||||
|                 else |                 else | ||||||
|                   if _class.implementedinterfaces.interfaces(intfindex).iitype = etStandard then |                   if ImplIntf.IntfDef.iitype = etStandard then | ||||||
|                     Message1(sym_e_no_matching_implementation_found,tprocdef(def).fullprocname(false)); |                     Message1(sym_e_no_matching_implementation_found,tprocdef(def).fullprocname(false)); | ||||||
|               end; |               end; | ||||||
|             def:=tdef(def.indexnext); |             def:=tdef(def.indexnext); | ||||||
| @ -1152,33 +1158,33 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tclassheader.gintfwalkdowninterface(intf: tobjectdef; intfindex: longint); |     procedure tclassheader.intf_get_procdefs_recursive(ImplIntf:TImplementedInterface;IntfDef:TObjectDef); | ||||||
|       begin |       begin | ||||||
|         if assigned(intf.childof) then |         if assigned(IntfDef.childof) then | ||||||
|           gintfwalkdowninterface(intf.childof,intfindex); |           intf_get_procdefs_recursive(ImplIntf,IntfDef.childof); | ||||||
|         gintfdoonintf(intf,intfindex); |         intf_get_procdefs(ImplIntf,IntfDef); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     function tclassheader.genintftable: tasmlabel; |     function tclassheader.genintftable: tasmlabel; | ||||||
|       var |       var | ||||||
|         intfindex: longint; |         ImplIntf  : TImplementedInterface; | ||||||
|         curintf: tobjectdef; |         intftable : tasmlabel; | ||||||
|         intftable: tasmlabel; |         i : longint; | ||||||
|       begin |       begin | ||||||
|         { 1. step collect implementor functions into the implementedinterfaces.implprocs } |         { 1. step collect implementor functions into the tImplementedInterface.procdefs } | ||||||
|         for intfindex:=1 to _class.implementedinterfaces.count do |         for i:=0 to _class.ImplementedInterfaces.count-1 do | ||||||
|           begin |           begin | ||||||
|             curintf:=_class.implementedinterfaces.interfaces(intfindex); |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|             gintfwalkdowninterface(curintf,intfindex); |             intf_get_procdefs_recursive(ImplIntf,ImplIntf.IntfDef); | ||||||
|           end; |           end; | ||||||
|         { 2. Optimize interface tables to reuse wrappers } |         { 2. Optimize interface tables to reuse wrappers } | ||||||
|         gintfoptimizevtbls; |         intf_optimize_vtbls; | ||||||
|         { 3. Calculate offsets in object map and Write interface tables } |         { 3. Calculate offsets in object map and Write interface tables } | ||||||
|         current_asmdata.getdatalabel(intftable); |         current_asmdata.getdatalabel(intftable); | ||||||
|         current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(aint)))); |         current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(aint)))); | ||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_label.Create(intftable)); |         current_asmdata.asmlists[al_globals].concat(Tai_label.Create(intftable)); | ||||||
|         gintfwritedata; |         intf_write_data; | ||||||
|         genintftable:=intftable; |         genintftable:=intftable; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| @ -1283,7 +1289,7 @@ implementation | |||||||
|             new_section(current_asmdata.asmlists[al_globals],sec_rodata,classnamelabel.name,const_align(sizeof(aint))); |             new_section(current_asmdata.asmlists[al_globals],sec_rodata,classnamelabel.name,const_align(sizeof(aint))); | ||||||
| 
 | 
 | ||||||
|             { interface table } |             { interface table } | ||||||
|             if _class.implementedinterfaces.count>0 then |             if _class.ImplementedInterfaces.count>0 then | ||||||
|               interfacetable:=genintftable; |               interfacetable:=genintftable; | ||||||
| 
 | 
 | ||||||
|             methodnametable:=genpublishedmethodstable; |             methodnametable:=genpublishedmethodstable; | ||||||
| @ -1355,7 +1361,7 @@ implementation | |||||||
|             { auto table } |             { auto table } | ||||||
|             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); |             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); | ||||||
|             { interface table } |             { interface table } | ||||||
|             if _class.implementedinterfaces.count>0 then |             if _class.ImplementedInterfaces.count>0 then | ||||||
|               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(interfacetable)) |               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(interfacetable)) | ||||||
|             else |             else | ||||||
|               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); |               current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); | ||||||
|  | |||||||
| @ -271,8 +271,8 @@ implementation | |||||||
|                       (((block_type=bt_type) and typecanbeforward) or |                       (((block_type=bt_type) and typecanbeforward) or | ||||||
|                        not(m_delphi in current_settings.modeswitches)) then |                        not(m_delphi in current_settings.modeswitches)) then | ||||||
|                      begin |                      begin | ||||||
|                         { a hack, but it's easy to handle } |                         { a hack, but it's easy to handle | ||||||
|                         { class reference type } |                           class reference type } | ||||||
|                         consume(_OF); |                         consume(_OF); | ||||||
|                         single_type(hdef,typecanbeforward); |                         single_type(hdef,typecanbeforward); | ||||||
| 
 | 
 | ||||||
| @ -322,28 +322,27 @@ implementation | |||||||
|            end; |            end; | ||||||
|         end; |         end; | ||||||
| 
 | 
 | ||||||
|       procedure handleimplementedinterface(implintf : tobjectdef); |       procedure handleImplementedInterface(intfdef : tobjectdef); | ||||||
| 
 | 
 | ||||||
|         begin |         begin | ||||||
|             if not is_interface(implintf) then |             if not is_interface(intfdef) then | ||||||
|               begin |               begin | ||||||
|                  Message1(type_e_interface_type_expected,implintf.typename); |                  Message1(type_e_interface_type_expected,intfdef.typename); | ||||||
|                  exit; |                  exit; | ||||||
|               end; |               end; | ||||||
|             if aktobjectdef.implementedinterfaces.searchintf(implintf)<>-1 then |             if aktobjectdef.find_implemented_interface(intfdef)<>nil then | ||||||
|               Message1(sym_e_duplicate_id,implintf.name) |               Message1(sym_e_duplicate_id,intfdef.name) | ||||||
|             else |             else | ||||||
|               begin |               begin | ||||||
|                 { allocate and prepare the GUID only if the class |                 { allocate and prepare the GUID only if the class | ||||||
|                    implements some interfaces. |                   implements some interfaces. } | ||||||
|                  } |                 if aktobjectdef.ImplementedInterfaces.count = 0 then | ||||||
|                  if aktobjectdef.implementedinterfaces.count = 0 then |  | ||||||
|                   aktobjectdef.prepareguid; |                   aktobjectdef.prepareguid; | ||||||
|                  aktobjectdef.implementedinterfaces.addintf(implintf); |                 aktobjectdef.ImplementedInterfaces.Add(TImplementedInterface.Create(intfdef)); | ||||||
|               end; |               end; | ||||||
|         end; |         end; | ||||||
| 
 | 
 | ||||||
|       procedure readimplementedinterfaces; |       procedure readImplementedInterfaces; | ||||||
|         var |         var | ||||||
|           hdef : tdef; |           hdef : tdef; | ||||||
|         begin |         begin | ||||||
| @ -355,7 +354,7 @@ implementation | |||||||
|                     Message1(type_e_interface_type_expected,hdef.typename); |                     Message1(type_e_interface_type_expected,hdef.typename); | ||||||
|                     continue; |                     continue; | ||||||
|                  end; |                  end; | ||||||
|                handleimplementedinterface(tobjectdef(hdef)); |                handleImplementedInterface(tobjectdef(hdef)); | ||||||
|             end; |             end; | ||||||
|         end; |         end; | ||||||
| 
 | 
 | ||||||
| @ -473,8 +472,8 @@ implementation | |||||||
|               if aktobjectdef.objecttype=odt_class then |               if aktobjectdef.objecttype=odt_class then | ||||||
|                 begin |                 begin | ||||||
|                   if assigned(intfchildof) then |                   if assigned(intfchildof) then | ||||||
|                     handleimplementedinterface(intfchildof); |                     handleImplementedInterface(intfchildof); | ||||||
|                   readimplementedinterfaces; |                   readImplementedInterfaces; | ||||||
|                 end; |                 end; | ||||||
|               consume(_RKLAMMER); |               consume(_RKLAMMER); | ||||||
|             end; |             end; | ||||||
|  | |||||||
| @ -630,6 +630,7 @@ implementation | |||||||
|         st : tsymtable; |         st : tsymtable; | ||||||
|         aprocsym : tprocsym; |         aprocsym : tprocsym; | ||||||
|         popclass : boolean; |         popclass : boolean; | ||||||
|  |         ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|         { Save the position where this procedure really starts } |         { Save the position where this procedure really starts } | ||||||
|         procstartfilepos:=current_tokenpos; |         procstartfilepos:=current_tokenpos; | ||||||
| @ -652,8 +653,8 @@ implementation | |||||||
| 
 | 
 | ||||||
|         { examine interface map: function/procedure iname.functionname=locfuncname } |         { examine interface map: function/procedure iname.functionname=locfuncname } | ||||||
|         if assigned(aclass) and |         if assigned(aclass) and | ||||||
|            assigned(aclass.implementedinterfaces) and |            assigned(aclass.ImplementedInterfaces) and | ||||||
|            (aclass.implementedinterfaces.count>0) and |            (aclass.ImplementedInterfaces.count>0) and | ||||||
|            try_to_consume(_POINT) then |            try_to_consume(_POINT) then | ||||||
|          begin |          begin | ||||||
|            storepos:=current_tokenpos; |            storepos:=current_tokenpos; | ||||||
| @ -667,20 +668,19 @@ implementation | |||||||
|             end; |             end; | ||||||
|            current_tokenpos:=storepos; |            current_tokenpos:=storepos; | ||||||
|            { qualifier is interface? } |            { qualifier is interface? } | ||||||
|  |            ImplIntf:=nil; | ||||||
|            if (srsym.typ=typesym) and |            if (srsym.typ=typesym) and | ||||||
|               (ttypesym(srsym).typedef.deftype=objectdef) then |               (ttypesym(srsym).typedef.deftype=objectdef) then | ||||||
|              i:=aclass.implementedinterfaces.searchintf(ttypesym(srsym).typedef) |              ImplIntf:=aclass.find_implemented_interface(tobjectdef(ttypesym(srsym).typedef)); | ||||||
|            else |            if ImplIntf=nil then | ||||||
|              i:=-1; |  | ||||||
|            if (i=-1) then |  | ||||||
|              Message(parser_e_interface_id_expected); |              Message(parser_e_interface_id_expected); | ||||||
|            consume(_ID); |            consume(_ID); | ||||||
|            { Create unique name <interface>.<method> } |            { Create unique name <interface>.<method> } | ||||||
|            hs:=sp+'.'+pattern; |            hs:=sp+'.'+pattern; | ||||||
|            consume(_EQUAL); |            consume(_EQUAL); | ||||||
|            if (i<>-1) and |            if assigned(ImplIntf) and | ||||||
|               (token=_ID) then |               (token=_ID) then | ||||||
|              aclass.implementedinterfaces.addmappings(i,hs,pattern); |              ImplIntf.AddMapping(hs,pattern); | ||||||
|            consume(_ID); |            consume(_ID); | ||||||
|            result:=true; |            result:=true; | ||||||
|            exit; |            exit; | ||||||
|  | |||||||
| @ -222,7 +222,8 @@ implementation | |||||||
|          sc : TFPObjectList; |          sc : TFPObjectList; | ||||||
|          paranr : word; |          paranr : word; | ||||||
|          i      : longint; |          i      : longint; | ||||||
|          intfidx: longint; |          ImplIntf     : TImplementedInterface; | ||||||
|  |          found        : boolean; | ||||||
|          hreadparavs, |          hreadparavs, | ||||||
|          hparavs      : tparavarsym; |          hparavs      : tparavarsym; | ||||||
|          storedprocdef, |          storedprocdef, | ||||||
| @ -611,36 +612,31 @@ implementation | |||||||
|          if try_to_consume(_IMPLEMENTS) then |          if try_to_consume(_IMPLEMENTS) then | ||||||
|            begin |            begin | ||||||
|              consume(_ID); |              consume(_ID); | ||||||
|            {$message warn unlocalized string} |  | ||||||
|              if not is_interface(p.propdef) then |              if not is_interface(p.propdef) then | ||||||
|                begin |                begin | ||||||
|              writeln('Implements property must have interface type'); |                  Comment(V_Error,'Implements property must have interface type'); | ||||||
|              Message1(sym_e_illegal_field, pattern); |  | ||||||
|                end; |                end; | ||||||
|              if pattern <> p.propdef.mangledparaname() then |              if pattern <> p.propdef.mangledparaname() then | ||||||
|                begin |                begin | ||||||
|              writeln('Implements-property must implement interface of correct type'); |                  Comment(V_Error,'Implements-property must implement interface of correct type'); | ||||||
|              Message1(sym_e_illegal_field, pattern); |  | ||||||
|                end; |                end; | ||||||
|            intfidx := 0; |              found:=false; | ||||||
|            with aclass.implementedinterfaces do |              for i:=0 to aclass.ImplementedInterfaces.Count-1 do | ||||||
|                begin |                begin | ||||||
|              for i := 1 to count do |                  ImplIntf:=TImplementedInterface(aclass.ImplementedInterfaces[i]); | ||||||
|                if interfaces(i).objname^ = pattern then |                  if ImplIntf.IntfDef.Objname^=pattern then | ||||||
|                    begin |                    begin | ||||||
|                  intfidx := i; |                      found:=true; | ||||||
|                      break; |                      break; | ||||||
|                    end; |                    end; | ||||||
|              if intfidx > 0 then |  | ||||||
|              begin |  | ||||||
|                interfaces(intfidx).iitype := etFieldValue; |  | ||||||
|                interfaces(intfidx).iioffset := tfieldvarsym(p.propaccesslist[palt_read].firstsym^.sym).fieldoffset; |  | ||||||
|              end else |  | ||||||
|              begin |  | ||||||
|                writeln('Implements-property used on unimplemented interface'); |  | ||||||
|                Message1(sym_e_illegal_field, pattern); |  | ||||||
|              end; |  | ||||||
|                end; |                end; | ||||||
|  |              if found then | ||||||
|  |                begin | ||||||
|  |                  ImplIntf.IntfDef.iitype := etFieldValue; | ||||||
|  |                  ImplIntf.IntfDef.iioffset := tfieldvarsym(p.propaccesslist[palt_read].firstsym^.sym).fieldoffset; | ||||||
|  |                end | ||||||
|  |              else | ||||||
|  |                Comment(V_Error,'Implements-property used on unimplemented interface'); | ||||||
|          end; |          end; | ||||||
| 
 | 
 | ||||||
|          { remove temporary procvardefs } |          { remove temporary procvardefs } | ||||||
|  | |||||||
| @ -213,20 +213,30 @@ interface | |||||||
| 
 | 
 | ||||||
|        tprocdef = class; |        tprocdef = class; | ||||||
|        tobjectdef = class; |        tobjectdef = class; | ||||||
|        timplementedinterfaces = class; |  | ||||||
| 
 | 
 | ||||||
|        timplintfentry = class(TNamedIndexItem) |        { TImplementedInterface } | ||||||
|          intf         : tobjectdef; | 
 | ||||||
|          intfderef    : tderef; |        TImplementedInterface = class | ||||||
|          ioffset      : longint; |          IntfDef      : tobjectdef; | ||||||
|          implindex    : longint; |          IntfDefDeref : tderef; | ||||||
|          namemappings : tdictionary; |          IOffset      : longint; | ||||||
|          procdefs     : TIndexArray; |          VtblImplIntf   : TImplementedInterface; | ||||||
|  |          NameMappings : TFPHashList; | ||||||
|  |          ProcDefs     : TFPObjectList; | ||||||
|          constructor create(aintf: tobjectdef); |          constructor create(aintf: tobjectdef); | ||||||
|          constructor create_deref(d:tderef); |          constructor create_deref(d:tderef); | ||||||
|          destructor  destroy; override; |          destructor  destroy; override; | ||||||
|  |          function  getcopy:TImplementedInterface; | ||||||
|  |          procedure buildderef; | ||||||
|  |          procedure deref; | ||||||
|  |          procedure AddMapping(const origname, newname: string); | ||||||
|  |          function  GetMapping(const origname: string):string; | ||||||
|  |          procedure AddImplProc(pd:tprocdef); | ||||||
|  |          function  IsImplMergePossible(MergingIntf:TImplementedInterface;out weight: longint): boolean; | ||||||
|        end; |        end; | ||||||
|         |         | ||||||
|  |        { tobjectdef } | ||||||
|  | 
 | ||||||
|        tobjectdef = class(tabstractrecorddef) |        tobjectdef = class(tabstractrecorddef) | ||||||
|        private |        private | ||||||
|           procedure count_published_properties(sym:tnamedindexitem;arg:pointer); |           procedure count_published_properties(sym:tnamedindexitem;arg:pointer); | ||||||
| @ -246,13 +256,13 @@ interface | |||||||
|           vmt_offset     : longint; |           vmt_offset     : longint; | ||||||
|           writing_class_record_dbginfo : boolean; |           writing_class_record_dbginfo : boolean; | ||||||
|           objecttype     : tobjectdeftype; |           objecttype     : tobjectdeftype; | ||||||
|           iidguid: pguid; |           iidguid        : pguid; | ||||||
|           iidstr: pshortstring; |           iidstr         : pshortstring; | ||||||
|           iitype: tinterfaceentrytype; |           iitype         : tinterfaceentrytype; | ||||||
|           iioffset: longint; |           iioffset       : longint; | ||||||
|           lastvtableindex: longint; |           lastvtableindex: longint; | ||||||
|           { store implemented interfaces defs and name mappings } |           { store implemented interfaces defs and name mappings } | ||||||
|           implementedinterfaces: timplementedinterfaces; |           ImplementedInterfaces : TFPObjectList; | ||||||
|           constructor create(ot : tobjectdeftype;const n : string;c : tobjectdef); |           constructor create(ot : tobjectdeftype;const n : string;c : tobjectdef); | ||||||
|           constructor ppuload(ppufile:tcompilerppufile); |           constructor ppuload(ppufile:tcompilerppufile); | ||||||
|           destructor  destroy;override; |           destructor  destroy;override; | ||||||
| @ -266,6 +276,7 @@ interface | |||||||
|           function  alignment:shortint;override; |           function  alignment:shortint;override; | ||||||
|           function  vmtmethodoffset(index:longint):longint; |           function  vmtmethodoffset(index:longint):longint; | ||||||
|           function  members_need_inittable : boolean; |           function  members_need_inittable : boolean; | ||||||
|  |           function  find_implemented_interface(aintfdef:tobjectdef):TImplementedInterface; | ||||||
|           { this should be called when this class implements an interface } |           { this should be called when this class implements an interface } | ||||||
|           procedure prepareguid; |           procedure prepareguid; | ||||||
|           function  is_publishable : boolean;override; |           function  is_publishable : boolean;override; | ||||||
| @ -283,41 +294,6 @@ interface | |||||||
|           function generate_field_table : tasmlabel; |           function generate_field_table : tasmlabel; | ||||||
|        end; |        end; | ||||||
| 
 | 
 | ||||||
|        timplementedinterfaces = class |  | ||||||
|           constructor create; |  | ||||||
|           destructor  destroy; override; |  | ||||||
| 
 |  | ||||||
|           function  count: longint; |  | ||||||
|           function  interfaces(intfindex: longint): tobjectdef; |  | ||||||
|           function  interfacesderef(intfindex: longint): tderef; |  | ||||||
|           function  ioffsets(intfindex: longint): longint; |  | ||||||
|           procedure setioffsets(intfindex,iofs:longint); |  | ||||||
|           function  implindex(intfindex:longint):longint; |  | ||||||
|           procedure setimplindex(intfindex,implidx:longint); |  | ||||||
|           function  searchintf(def: tdef): longint; |  | ||||||
|           procedure addintf(def: tdef); |  | ||||||
| 
 |  | ||||||
|           procedure buildderef; |  | ||||||
|           procedure deref; |  | ||||||
|           { add interface reference loaded from ppu } |  | ||||||
|           procedure addintf_deref(const d:tderef;iofs:longint); |  | ||||||
|           procedure addintf_ioffset(d:tdef;iofs:longint); |  | ||||||
| 
 |  | ||||||
|           procedure clearmappings; |  | ||||||
|           procedure addmappings(intfindex: longint; const origname, newname: string); |  | ||||||
|           function  getmappings(intfindex: longint; const origname: string; var nextexist: pointer): string; |  | ||||||
| 
 |  | ||||||
|           procedure addimplproc(intfindex: longint; procdef: tprocdef); |  | ||||||
|           function  implproccount(intfindex: longint): longint; |  | ||||||
|           function  implprocs(intfindex: longint; procindex: longint): tprocdef; |  | ||||||
|           function  isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean; |  | ||||||
| 
 |  | ||||||
|        private |  | ||||||
|           finterfaces: tindexarray; |  | ||||||
|           procedure checkindex(intfindex: longint); |  | ||||||
|        end; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|        tclassrefdef = class(tabstractpointerdef) |        tclassrefdef = class(tabstractpointerdef) | ||||||
|           constructor create(def:tdef); |           constructor create(def:tdef); | ||||||
|           constructor ppuload(ppufile:tcompilerppufile); |           constructor ppuload(ppufile:tcompilerppufile); | ||||||
| @ -4380,9 +4356,9 @@ implementation | |||||||
|           prepareguid; |           prepareguid; | ||||||
|         { setup implemented interfaces } |         { setup implemented interfaces } | ||||||
|         if objecttype in [odt_class,odt_interfacecorba] then |         if objecttype in [odt_class,odt_interfacecorba] then | ||||||
|           implementedinterfaces:=timplementedinterfaces.create |           ImplementedInterfaces:=TFPObjectList.Create(true) | ||||||
|         else |         else | ||||||
|           implementedinterfaces:=nil; |           ImplementedInterfaces:=nil; | ||||||
|         writing_class_record_dbginfo:=false; |         writing_class_record_dbginfo:=false; | ||||||
|         iitype := etStandard; |         iitype := etStandard; | ||||||
|      end; |      end; | ||||||
| @ -4390,8 +4366,10 @@ implementation | |||||||
| 
 | 
 | ||||||
|     constructor tobjectdef.ppuload(ppufile:tcompilerppufile); |     constructor tobjectdef.ppuload(ppufile:tcompilerppufile); | ||||||
|       var |       var | ||||||
|          i,implintfcount: longint; |          i, | ||||||
|  |          implintfcount : longint; | ||||||
|          d : tderef; |          d : tderef; | ||||||
|  |          ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|          inherited ppuload(objectdef,ppufile); |          inherited ppuload(objectdef,ppufile); | ||||||
|          objecttype:=tobjectdeftype(ppufile.getbyte); |          objecttype:=tobjectdeftype(ppufile.getbyte); | ||||||
| @ -4418,16 +4396,18 @@ implementation | |||||||
|          { load implemented interfaces } |          { load implemented interfaces } | ||||||
|          if objecttype in [odt_class,odt_interfacecorba] then |          if objecttype in [odt_class,odt_interfacecorba] then | ||||||
|            begin |            begin | ||||||
|              implementedinterfaces:=timplementedinterfaces.create; |              ImplementedInterfaces:=TFPObjectList.Create(true); | ||||||
|              implintfcount:=ppufile.getlongint; |              implintfcount:=ppufile.getlongint; | ||||||
|              for i:=1 to implintfcount do |              for i:=0 to implintfcount-1 do | ||||||
|                begin |                begin | ||||||
|                  ppufile.getderef(d); |                  ppufile.getderef(d); | ||||||
|                   implementedinterfaces.addintf_deref(d,ppufile.getlongint); |                  ImplIntf:=TImplementedInterface.Create_deref(d); | ||||||
|  |                  ImplIntf.IOffset:=ppufile.getlongint; | ||||||
|  |                  ImplementedInterfaces.Add(ImplIntf); | ||||||
|                end; |                end; | ||||||
|            end |            end | ||||||
|          else |          else | ||||||
|            implementedinterfaces:=nil; |            ImplementedInterfaces:=nil; | ||||||
| 
 | 
 | ||||||
|          tobjectsymtable(symtable).ppuload(ppufile); |          tobjectsymtable(symtable).ppuload(ppufile); | ||||||
| 
 | 
 | ||||||
| @ -4455,8 +4435,8 @@ implementation | |||||||
|          stringdispose(objrealname); |          stringdispose(objrealname); | ||||||
|          if assigned(iidstr) then |          if assigned(iidstr) then | ||||||
|            stringdispose(iidstr); |            stringdispose(iidstr); | ||||||
|          if assigned(implementedinterfaces) then |          if assigned(ImplementedInterfaces) then | ||||||
|            implementedinterfaces.free; |            ImplementedInterfaces.free; | ||||||
|          if assigned(iidguid) then |          if assigned(iidguid) then | ||||||
|            dispose(iidguid); |            dispose(iidguid); | ||||||
|          inherited destroy; |          inherited destroy; | ||||||
| @ -4465,8 +4445,7 @@ implementation | |||||||
| 
 | 
 | ||||||
|     function tobjectdef.getcopy : tstoreddef; |     function tobjectdef.getcopy : tstoreddef; | ||||||
|       var |       var | ||||||
|         i, |         i : longint; | ||||||
|         implintfcount : longint; |  | ||||||
|       begin |       begin | ||||||
|         result:=tobjectdef.create(objecttype,objname^,childof); |         result:=tobjectdef.create(objecttype,objname^,childof); | ||||||
|         tobjectdef(result).symtable:=symtable.getcopy; |         tobjectdef(result).symtable:=symtable.getcopy; | ||||||
| @ -4484,22 +4463,18 @@ implementation | |||||||
|         if assigned(iidstr) then |         if assigned(iidstr) then | ||||||
|           tobjectdef(result).iidstr:=stringdup(iidstr^); |           tobjectdef(result).iidstr:=stringdup(iidstr^); | ||||||
|         tobjectdef(result).lastvtableindex:=lastvtableindex; |         tobjectdef(result).lastvtableindex:=lastvtableindex; | ||||||
|         if assigned(implementedinterfaces) then |         if assigned(ImplementedInterfaces) then | ||||||
|           begin |           begin | ||||||
|             implintfcount:=implementedinterfaces.count; |             for i:=0 to ImplementedInterfaces.count-1 do | ||||||
|             for i:=1 to implintfcount do |               tobjectdef(result).ImplementedInterfaces.Add(TImplementedInterface(ImplementedInterfaces[i]).Getcopy); | ||||||
|               begin |  | ||||||
|                 tobjectdef(result).implementedinterfaces.addintf_ioffset(implementedinterfaces.interfaces(i), |  | ||||||
|                     implementedinterfaces.ioffsets(i)); |  | ||||||
|               end; |  | ||||||
|           end; |           end; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile); |     procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile); | ||||||
|       var |       var | ||||||
|          implintfcount : longint; |  | ||||||
|          i : longint; |          i : longint; | ||||||
|  |          ImplIntf : TImplementedInterface; | ||||||
|       begin |       begin | ||||||
|          inherited ppuwrite(ppufile); |          inherited ppuwrite(ppufile); | ||||||
|          ppufile.putbyte(byte(objecttype)); |          ppufile.putbyte(byte(objecttype)); | ||||||
| @ -4519,12 +4494,12 @@ implementation | |||||||
| 
 | 
 | ||||||
|          if objecttype in [odt_class,odt_interfacecorba] then |          if objecttype in [odt_class,odt_interfacecorba] then | ||||||
|            begin |            begin | ||||||
|               implintfcount:=implementedinterfaces.count; |              ppufile.putlongint(ImplementedInterfaces.Count); | ||||||
|               ppufile.putlongint(implintfcount); |              for i:=0 to ImplementedInterfaces.Count-1 do | ||||||
|               for i:=1 to implintfcount do |  | ||||||
|                begin |                begin | ||||||
|                    ppufile.putderef(implementedinterfaces.interfacesderef(i)); |                  ImplIntf:=TImplementedInterface(ImplementedInterfaces[i]); | ||||||
|                    ppufile.putlongint(implementedinterfaces.ioffsets(i)); |                  ppufile.putderef(ImplIntf.intfdefderef); | ||||||
|  |                  ppufile.putlongint(ImplIntf.Ioffset); | ||||||
|                end; |                end; | ||||||
|            end; |            end; | ||||||
| 
 | 
 | ||||||
| @ -4549,6 +4524,7 @@ implementation | |||||||
| 
 | 
 | ||||||
|     procedure tobjectdef.buildderef; |     procedure tobjectdef.buildderef; | ||||||
|       var |       var | ||||||
|  |          i : longint; | ||||||
|          oldrecsyms : tsymtable; |          oldrecsyms : tsymtable; | ||||||
|       begin |       begin | ||||||
|          inherited buildderef; |          inherited buildderef; | ||||||
| @ -4558,12 +4534,16 @@ implementation | |||||||
|          tstoredsymtable(symtable).buildderef; |          tstoredsymtable(symtable).buildderef; | ||||||
|          aktrecordsymtable:=oldrecsyms; |          aktrecordsymtable:=oldrecsyms; | ||||||
|          if objecttype in [odt_class,odt_interfacecorba] then |          if objecttype in [odt_class,odt_interfacecorba] then | ||||||
|            implementedinterfaces.buildderef; |            begin | ||||||
|  |              for i:=0 to ImplementedInterfaces.count-1 do | ||||||
|  |                TImplementedInterface(ImplementedInterfaces[i]).buildderef; | ||||||
|  |            end; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure tobjectdef.deref; |     procedure tobjectdef.deref; | ||||||
|       var |       var | ||||||
|  |          i : longint; | ||||||
|          oldrecsyms : tsymtable; |          oldrecsyms : tsymtable; | ||||||
|       begin |       begin | ||||||
|          inherited deref; |          inherited deref; | ||||||
| @ -4573,7 +4553,10 @@ implementation | |||||||
|          tstoredsymtable(symtable).deref; |          tstoredsymtable(symtable).deref; | ||||||
|          aktrecordsymtable:=oldrecsyms; |          aktrecordsymtable:=oldrecsyms; | ||||||
|          if objecttype in [odt_class,odt_interfacecorba] then |          if objecttype in [odt_class,odt_interfacecorba] then | ||||||
|            implementedinterfaces.deref; |            begin | ||||||
|  |              for i:=0 to ImplementedInterfaces.count-1 do | ||||||
|  |                TImplementedInterface(ImplementedInterfaces[i]).deref; | ||||||
|  |            end; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -4796,6 +4779,26 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     function tobjectdef.find_implemented_interface(aintfdef:tobjectdef):TImplementedInterface; | ||||||
|  |       var | ||||||
|  |         ImplIntf : TImplementedInterface; | ||||||
|  |         i : longint; | ||||||
|  |       begin | ||||||
|  |         result:=nil; | ||||||
|  |         if not assigned(ImplementedInterfaces) then | ||||||
|  |           exit; | ||||||
|  |         for i:=0 to ImplementedInterfaces.Count-1 do | ||||||
|  |           begin | ||||||
|  |             ImplIntf:=TImplementedInterface(ImplementedInterfaces[i]); | ||||||
|  |             if ImplIntf.intfdef=aintfdef then | ||||||
|  |               begin | ||||||
|  |                 result:=ImplIntf; | ||||||
|  |                 exit; | ||||||
|  |               end; | ||||||
|  |           end; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     procedure tobjectdef.collect_published_properties(sym:tnamedindexitem;arg:pointer); |     procedure tobjectdef.collect_published_properties(sym:tnamedindexitem;arg:pointer); | ||||||
|       var |       var | ||||||
|         hp : tpropnamelistitem; |         hp : tpropnamelistitem; | ||||||
| @ -5199,301 +5202,133 @@ implementation | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| {**************************************************************************** | {**************************************************************************** | ||||||
|                              TIMPLEMENTEDINTERFACES |                              TImplementedInterface | ||||||
| ****************************************************************************} | ****************************************************************************} | ||||||
|     type |  | ||||||
|       tnamemap = class(TNamedIndexItem) |  | ||||||
|         listnext : TNamedIndexItem; |  | ||||||
|         newname: pshortstring; |  | ||||||
|         constructor create(const aname, anewname: string); |  | ||||||
|         destructor  destroy; override; |  | ||||||
|       end; |  | ||||||
| 
 | 
 | ||||||
|     constructor tnamemap.create(const aname, anewname: string); |     constructor TImplementedInterface.create(aintf: tobjectdef); | ||||||
|       begin |  | ||||||
|         inherited createname(aname); |  | ||||||
|         newname:=stringdup(anewname); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     destructor  tnamemap.destroy; |  | ||||||
|       begin |  | ||||||
|         stringdispose(newname); |  | ||||||
|         inherited destroy; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     type |  | ||||||
|       tprocdefstore = class(TNamedIndexItem) |  | ||||||
|         procdef: tprocdef; |  | ||||||
|         constructor create(aprocdef: tprocdef); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     constructor tprocdefstore.create(aprocdef: tprocdef); |  | ||||||
|       begin |       begin | ||||||
|         inherited create; |         inherited create; | ||||||
|         procdef:=aprocdef; |         intfdef:=aintf; | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     constructor timplintfentry.create(aintf: tobjectdef); |  | ||||||
|       begin |  | ||||||
|         inherited create; |  | ||||||
|         intf:=aintf; |  | ||||||
|         ioffset:=-1; |         ioffset:=-1; | ||||||
|         namemappings:=nil; |         NameMappings:=nil; | ||||||
|         procdefs:=nil; |         procdefs:=nil; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     constructor timplintfentry.create_deref(d:tderef); |     constructor TImplementedInterface.create_deref(d:tderef); | ||||||
|       begin |       begin | ||||||
|         inherited create; |         inherited create; | ||||||
|         intf:=nil; |         intfdef:=nil; | ||||||
|         intfderef:=d; |         intfdefderef:=d; | ||||||
|         ioffset:=-1; |         ioffset:=-1; | ||||||
|         namemappings:=nil; |         NameMappings:=nil; | ||||||
|         procdefs:=nil; |         procdefs:=nil; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     destructor  timplintfentry.destroy; |     destructor  TImplementedInterface.destroy; | ||||||
|  |       var | ||||||
|  |         i : longint; | ||||||
|  |         mappedname : pshortstring; | ||||||
|       begin |       begin | ||||||
|         if assigned(namemappings) then |         if assigned(NameMappings) then | ||||||
|           namemappings.free; |           begin | ||||||
|  |             for i:=0 to NameMappings.Count-1 do | ||||||
|  |               begin | ||||||
|  |                 mappedname:=pshortstring(NameMappings[i]); | ||||||
|  |                 stringdispose(mappedname); | ||||||
|  |               end; | ||||||
|  |             NameMappings.free; | ||||||
|  |           end; | ||||||
|         if assigned(procdefs) then |         if assigned(procdefs) then | ||||||
|           procdefs.free; |           procdefs.free; | ||||||
|         inherited destroy; |         inherited destroy; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     constructor timplementedinterfaces.create; |     procedure TImplementedInterface.buildderef; | ||||||
|       begin |       begin | ||||||
|         finterfaces:=tindexarray.create(1); |         intfdefderef.build(intfdef); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
|     destructor  timplementedinterfaces.destroy; | 
 | ||||||
|  |     procedure TImplementedInterface.deref; | ||||||
|       begin |       begin | ||||||
|         finterfaces.destroy; |         intfdef:=tobjectdef(intfdefderef.resolve); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
|     function  timplementedinterfaces.count: longint; | 
 | ||||||
|  |     procedure TImplementedInterface.AddMapping(const origname,newname: string); | ||||||
|       begin |       begin | ||||||
|         count:=finterfaces.count; |         if not assigned(NameMappings) then | ||||||
|  |           NameMappings:=TFPHashList.Create; | ||||||
|  |         NameMappings.Add(origname,stringdup(newname)); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
|     procedure timplementedinterfaces.checkindex(intfindex: longint); |  | ||||||
|       begin |  | ||||||
|         if (intfindex<1) or (intfindex>count) then |  | ||||||
|           InternalError(200006123); |  | ||||||
|       end; |  | ||||||
| 
 | 
 | ||||||
|     function  timplementedinterfaces.interfaces(intfindex: longint): tobjectdef; |     function TImplementedInterface.GetMapping(const origname: string):string; | ||||||
|  |       var | ||||||
|  |         mappedname : pshortstring; | ||||||
|       begin |       begin | ||||||
|         checkindex(intfindex); |         result:=''; | ||||||
|         interfaces:=timplintfentry(finterfaces.search(intfindex)).intf; |         if not assigned(NameMappings) then | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function  timplementedinterfaces.interfacesderef(intfindex: longint): tderef; |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         interfacesderef:=timplintfentry(finterfaces.search(intfindex)).intfderef; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function  timplementedinterfaces.ioffsets(intfindex: longint): longint; |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         ioffsets:=timplintfentry(finterfaces.search(intfindex)).ioffset; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.setioffsets(intfindex,iofs:longint); |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         timplintfentry(finterfaces.search(intfindex)).ioffset:=iofs; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function timplementedinterfaces.implindex(intfindex:longint):longint; |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         result:=timplintfentry(finterfaces.search(intfindex)).implindex; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.setimplindex(intfindex,implidx:longint); |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         timplintfentry(finterfaces.search(intfindex)).implindex:=implidx; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function  timplementedinterfaces.searchintf(def: tdef): longint; |  | ||||||
|       begin |  | ||||||
|         for result := 1 to count do |  | ||||||
|           if tdef(interfaces(result)) = def then |  | ||||||
|           exit; |           exit; | ||||||
|         result := -1; |         mappedname:=PShortstring(NameMappings.Find(origname)); | ||||||
|  |         if assigned(mappedname) then | ||||||
|  |           result:=mappedname^; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     procedure timplementedinterfaces.buildderef; |     procedure TImplementedInterface.AddImplProc(pd:tprocdef); | ||||||
|       var |       var | ||||||
|         i: longint; |  | ||||||
|       begin |  | ||||||
|         for i:=1 to count do |  | ||||||
|           with timplintfentry(finterfaces.search(i)) do |  | ||||||
|             intfderef.build(intf); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.deref; |  | ||||||
|       var |  | ||||||
|         i: longint; |  | ||||||
|       begin |  | ||||||
|         for i:=1 to count do |  | ||||||
|           with timplintfentry(finterfaces.search(i)) do |  | ||||||
|             intf:=tobjectdef(intfderef.resolve); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.addintf_deref(const d:tderef;iofs:longint); |  | ||||||
|       var |  | ||||||
|         hintf : timplintfentry; |  | ||||||
|       begin |  | ||||||
|         hintf:=timplintfentry.create_deref(d); |  | ||||||
|         hintf.ioffset:=iofs; |  | ||||||
|         finterfaces.insert(hintf); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.addintf_ioffset(d:tdef;iofs:longint); |  | ||||||
|       var |  | ||||||
|         hintf : timplintfentry; |  | ||||||
|       begin |  | ||||||
|         hintf:=timplintfentry.create(tobjectdef(d)); |  | ||||||
|         hintf.ioffset:=iofs; |  | ||||||
|         finterfaces.insert(hintf); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.addintf(def: tdef); |  | ||||||
|       begin |  | ||||||
|         if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or |  | ||||||
|            not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then |  | ||||||
|           internalerror(200006124); |  | ||||||
|         finterfaces.insert(timplintfentry.create(tobjectdef(def))); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.clearmappings; |  | ||||||
|       var |  | ||||||
|         i: longint; |  | ||||||
|       begin |  | ||||||
|         for i:=1 to count do |  | ||||||
|           with timplintfentry(finterfaces.search(i)) do |  | ||||||
|             begin |  | ||||||
|               if assigned(namemappings) then |  | ||||||
|                 namemappings.free; |  | ||||||
|               namemappings:=nil; |  | ||||||
|             end; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.addmappings(intfindex: longint; const origname, newname: string); |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         with timplintfentry(finterfaces.search(intfindex)) do |  | ||||||
|           begin |  | ||||||
|             if not assigned(namemappings) then |  | ||||||
|               namemappings:=tdictionary.create; |  | ||||||
|             namemappings.insert(tnamemap.create(origname,newname)); |  | ||||||
|           end; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function  timplementedinterfaces.getmappings(intfindex: longint; const origname: string; var nextexist: pointer): string; |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         if not assigned(nextexist) then |  | ||||||
|           with timplintfentry(finterfaces.search(intfindex)) do |  | ||||||
|             begin |  | ||||||
|               if assigned(namemappings) then |  | ||||||
|                 nextexist:=namemappings.search(origname) |  | ||||||
|               else |  | ||||||
|                 nextexist:=nil; |  | ||||||
|             end; |  | ||||||
|         if assigned(nextexist) then |  | ||||||
|           begin |  | ||||||
|             getmappings:=tnamemap(nextexist).newname^; |  | ||||||
|             nextexist:=tnamemap(nextexist).listnext; |  | ||||||
|           end |  | ||||||
|         else |  | ||||||
|           getmappings:=''; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef); |  | ||||||
|       var |  | ||||||
|         found : boolean; |  | ||||||
|         i : longint; |         i : longint; | ||||||
|       begin |         found : boolean; | ||||||
|         checkindex(intfindex); |  | ||||||
|         with timplintfentry(finterfaces.search(intfindex)) do |  | ||||||
|       begin |       begin | ||||||
|         if not assigned(procdefs) then |         if not assigned(procdefs) then | ||||||
|               procdefs:=tindexarray.create(4); |           procdefs:=TFPObjectList.Create(false); | ||||||
|         { No duplicate entries of the same procdef } |         { No duplicate entries of the same procdef } | ||||||
|         found:=false; |         found:=false; | ||||||
|             for i:=1 to procdefs.count do |         for i:=0 to procdefs.count-1 do | ||||||
|               if tprocdefstore(procdefs.search(i)).procdef=procdef then |           if tprocdef(procdefs[i])=pd then | ||||||
|             begin |             begin | ||||||
|               found:=true; |               found:=true; | ||||||
|               break; |               break; | ||||||
|             end; |             end; | ||||||
|         if not found then |         if not found then | ||||||
|               procdefs.insert(tprocdefstore.create(procdef)); |           procdefs.Add(pd); | ||||||
|           end; |  | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
|     function  timplementedinterfaces.implproccount(intfindex: longint): longint; |  | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         with timplintfentry(finterfaces.search(intfindex)) do |  | ||||||
|           if assigned(procdefs) then |  | ||||||
|             implproccount:=procdefs.count |  | ||||||
|           else |  | ||||||
|             implproccount:=0; |  | ||||||
|       end; |  | ||||||
| 
 | 
 | ||||||
|     function  timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef; |     function TImplementedInterface.IsImplMergePossible(MergingIntf:TImplementedInterface;out weight: longint): boolean; | ||||||
|       begin |  | ||||||
|         checkindex(intfindex); |  | ||||||
|         with timplintfentry(finterfaces.search(intfindex)) do |  | ||||||
|           if assigned(procdefs) then |  | ||||||
|             implprocs:=tprocdefstore(procdefs.search(procindex)).procdef |  | ||||||
|           else |  | ||||||
|             internalerror(200006131); |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
|     function  timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean; |  | ||||||
|       var |       var | ||||||
|         possible: boolean; |         i : longint; | ||||||
|         i: longint; |  | ||||||
|         iiep1: TIndexArray; |  | ||||||
|         iiep2: TIndexArray; |  | ||||||
|       begin |       begin | ||||||
|         checkindex(intfindex); |         result:=false; | ||||||
|         checkindex(remainindex); |  | ||||||
|         iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs; |  | ||||||
|         iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs; |  | ||||||
|         if not assigned(iiep1) then { empty interface is mergeable :-) } |  | ||||||
|           begin |  | ||||||
|             possible:=true; |  | ||||||
|         weight:=0; |         weight:=0; | ||||||
|           end |         { empty interface is mergeable } | ||||||
|         else |         if ProcDefs.Count=0 then | ||||||
|           begin |           begin | ||||||
|             possible:=assigned(iiep2) and (iiep1.count<=iiep2.count); |             result:=true; | ||||||
|             i:=1; |             exit; | ||||||
|             while (possible) and (i<=iiep1.count) do |           end; | ||||||
|  |         { The interface to merge must at least the number of | ||||||
|  |           procedures of this interface } | ||||||
|  |         if MergingIntf.ProcDefs.Count<ProcDefs.Count then | ||||||
|  |           exit; | ||||||
|  |         for i:=0 to ProcDefs.Count-1 do | ||||||
|           begin |           begin | ||||||
|                 possible:= |             if MergingIntf.ProcDefs[i]<>ProcDefs[i] then | ||||||
|                   (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef); |               exit; | ||||||
|                 inc(i); |  | ||||||
|           end; |           end; | ||||||
|             if possible then |         weight:=ProcDefs.Count; | ||||||
|               weight:=iiep1.count; |         result:=true; | ||||||
|       end; |       end; | ||||||
|         isimplmergepossible:=possible; | 
 | ||||||
|  | 
 | ||||||
|  |     function TImplementedInterface.getcopy:TImplementedInterface; | ||||||
|  |       begin | ||||||
|  |         Result:=TImplementedInterface.Create(nil); | ||||||
|  |         Move(pointer(self)^,pointer(result)^,InstanceSize); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 peter
						peter