浏览代码

compiler: handle dispinterfaces the same way as com interfaces because they are IDispatch descendants: increment/decrement they references in assignments and parameters passing by _AddRef, _Release

git-svn-id: trunk@16755 -
paul 14 年之前
父节点
当前提交
dad8313512
共有 5 个文件被更改,包括 20 次插入11 次删除
  1. 4 4
      compiler/cgobj.pas
  2. 1 1
      compiler/defcmp.pas
  3. 2 2
      compiler/nld.pas
  4. 2 2
      compiler/nutils.pas
  5. 11 2
      compiler/symdef.pas

+ 4 - 4
compiler/cgobj.pas

@@ -3473,7 +3473,7 @@ implementation
          cgpara2.init;
          cgpara2.init;
          paramanager.getintparaloc(pocall_default,1,cgpara1);
          paramanager.getintparaloc(pocall_default,1,cgpara1);
          paramanager.getintparaloc(pocall_default,2,cgpara2);
          paramanager.getintparaloc(pocall_default,2,cgpara2);
-         if is_interfacecom(t) then
+         if is_interfacecom_or_dispinterface(t) then
            incrfunc:='FPC_INTF_INCR_REF'
            incrfunc:='FPC_INTF_INCR_REF'
          else if is_ansistring(t) then
          else if is_ansistring(t) then
            incrfunc:='FPC_ANSISTR_INCR_REF'
            incrfunc:='FPC_ANSISTR_INCR_REF'
@@ -3529,7 +3529,7 @@ implementation
         paramanager.getintparaloc(pocall_default,1,cgpara1);
         paramanager.getintparaloc(pocall_default,1,cgpara1);
         paramanager.getintparaloc(pocall_default,2,cgpara2);
         paramanager.getintparaloc(pocall_default,2,cgpara2);
         needrtti:=false;
         needrtti:=false;
-        if is_interfacecom(t) then
+        if is_interfacecom_or_dispinterface(t) then
           decrfunc:='FPC_INTF_DECR_REF'
           decrfunc:='FPC_INTF_DECR_REF'
         else if is_ansistring(t) then
         else if is_ansistring(t) then
           decrfunc:='FPC_ANSISTR_DECR_REF'
           decrfunc:='FPC_ANSISTR_DECR_REF'
@@ -3593,7 +3593,7 @@ implementation
          if is_ansistring(t) or
          if is_ansistring(t) or
             is_widestring(t) or
             is_widestring(t) or
             is_unicodestring(t) or
             is_unicodestring(t) or
-            is_interfacecom(t) or
+            is_interfacecom_or_dispinterface(t) or
             is_dynamic_array(t) then
             is_dynamic_array(t) then
            a_load_const_ref(list,OS_ADDR,0,ref)
            a_load_const_ref(list,OS_ADDR,0,ref)
          else
          else
@@ -3624,7 +3624,7 @@ implementation
          if is_ansistring(t) or
          if is_ansistring(t) or
             is_widestring(t) or
             is_widestring(t) or
             is_unicodestring(t) or
             is_unicodestring(t) or
-            is_interfacecom(t) then
+            is_interfacecom_or_dispinterface(t) then
             begin
             begin
               g_decrrefcount(list,t,ref);
               g_decrrefcount(list,t,ref);
               a_load_const_ref(list,OS_ADDR,0,ref);
               a_load_const_ref(list,OS_ADDR,0,ref);

+ 1 - 1
compiler/defcmp.pas

@@ -1445,7 +1445,7 @@ implementation
              begin
              begin
                { interface -> guid }
                { interface -> guid }
                if (def_to=rec_tguid) and
                if (def_to=rec_tguid) and
-                  (is_interfacecom(def_from) or is_dispinterface(def_from)) then
+                  (is_interfacecom_or_dispinterface(def_from)) then
                 begin
                 begin
                   doconv:=tc_intf_2_guid;
                   doconv:=tc_intf_2_guid;
                   eq:=te_convert_l1;
                   eq:=te_convert_l1;

+ 2 - 2
compiler/nld.pas

@@ -626,7 +626,7 @@ implementation
           end;
           end;
 
 
         { call helpers for interface }
         { call helpers for interface }
-        if is_interfacecom(left.resultdef) then
+        if is_interfacecom_or_dispinterface(left.resultdef) then
          begin
          begin
 	   { Normal interface assignments are handled by the generic refcount incr/decr }
 	   { Normal interface assignments are handled by the generic refcount incr/decr }
            if not right.resultdef.is_related(left.resultdef) then
            if not right.resultdef.is_related(left.resultdef) then
@@ -712,7 +712,7 @@ implementation
         { call helpers for composite types containing automated types }
         { call helpers for composite types containing automated types }
         else if is_managed_type(left.resultdef) and
         else if is_managed_type(left.resultdef) and
             (left.resultdef.typ in [arraydef,objectdef,recorddef]) and
             (left.resultdef.typ in [arraydef,objectdef,recorddef]) and
-            not is_interfacecom(left.resultdef) and
+            not is_interfacecom_or_dispinterface(left.resultdef) and
             not is_dynamic_array(left.resultdef) then
             not is_dynamic_array(left.resultdef) then
          begin
          begin
            hp:=ccallparanode.create(caddrnode.create_internal(
            hp:=ccallparanode.create(caddrnode.create_internal(

+ 2 - 2
compiler/nutils.pas

@@ -592,7 +592,7 @@ implementation
           typecheckpass(p);
           typecheckpass(p);
         if is_ansistring(p.resultdef) or
         if is_ansistring(p.resultdef) or
            is_wide_or_unicode_string(p.resultdef) or
            is_wide_or_unicode_string(p.resultdef) or
-           is_interfacecom(p.resultdef) or
+           is_interfacecom_or_dispinterface(p.resultdef) or
            is_dynamic_array(p.resultdef) then
            is_dynamic_array(p.resultdef) then
           begin
           begin
             result:=cassignmentnode.create(
             result:=cassignmentnode.create(
@@ -656,7 +656,7 @@ implementation
                cnilnode.create
                cnilnode.create
                ));
                ));
           end
           end
-        else if is_interfacecom(p.resultdef) then
+        else if is_interfacecom_or_dispinterface(p.resultdef) then
           begin
           begin
             result:=internalstatements(newstatement);
             result:=internalstatements(newstatement);
             addstatement(newstatement,ccallnode.createintern('fpc_intf_decr_ref',
             addstatement(newstatement,ccallnode.createintern('fpc_intf_decr_ref',

+ 11 - 2
compiler/symdef.pas

@@ -768,6 +768,7 @@ interface
 
 
     { should be in the types unit, but the types unit uses the node stuff :( }
     { should be in the types unit, but the types unit uses the node stuff :( }
     function is_interfacecom(def: tdef): boolean;
     function is_interfacecom(def: tdef): boolean;
+    function is_interfacecom_or_dispinterface(def: tdef): boolean;
     function is_interfacecorba(def: tdef): boolean;
     function is_interfacecorba(def: tdef): boolean;
     function is_interface(def: tdef): boolean;
     function is_interface(def: tdef): boolean;
     function is_dispinterface(def: tdef): boolean;
     function is_dispinterface(def: tdef): boolean;
@@ -4645,7 +4646,7 @@ implementation
         odt_objcclass,
         odt_objcclass,
         odt_objcprotocol:
         odt_objcprotocol:
           vmtmethodoffset:=0;
           vmtmethodoffset:=0;
-        odt_interfacecom,odt_interfacecorba:
+        odt_interfacecom,odt_interfacecorba,odt_dispinterface:
           vmtmethodoffset:=index*sizeof(pint);
           vmtmethodoffset:=index*sizeof(pint);
         else
         else
 {$ifdef WITHDMT}
 {$ifdef WITHDMT}
@@ -4668,9 +4669,9 @@ implementation
     function tobjectdef.needs_inittable : boolean;
     function tobjectdef.needs_inittable : boolean;
       begin
       begin
          case objecttype of
          case objecttype of
-            odt_dispinterface,
             odt_class :
             odt_class :
               needs_inittable:=false;
               needs_inittable:=false;
+            odt_dispinterface,
             odt_interfacecom:
             odt_interfacecom:
               needs_inittable:=true;
               needs_inittable:=true;
             odt_interfacecorba:
             odt_interfacecorba:
@@ -5364,6 +5365,14 @@ implementation
           (tobjectdef(def).objecttype=odt_interfacecom);
           (tobjectdef(def).objecttype=odt_interfacecom);
       end;
       end;
 
 
+    function is_interfacecom_or_dispinterface(def: tdef): boolean;
+      begin
+        is_interfacecom_or_dispinterface:=
+          assigned(def) and
+          (def.typ=objectdef) and
+          (tobjectdef(def).objecttype in [odt_interfacecom,odt_dispinterface]);
+      end;
+
     function is_interfacecorba(def: tdef): boolean;
     function is_interfacecorba(def: tdef): boolean;
       begin
       begin
         is_interfacecorba:=
         is_interfacecorba:=