Browse Source

* replace the contents of the dummy self and msgsel parameters when
transforming objc-calls, rather than adding new such parameters
(fixes calling objc-methods on ppc)

git-svn-id: branches/objc@13174 -

Jonas Maebe 16 years ago
parent
commit
5691da116f
1 changed files with 27 additions and 12 deletions
  1. 27 12
      compiler/nobjc.pas

+ 27 - 12
compiler/nobjc.pas

@@ -191,12 +191,14 @@ function tobjcmessagesendnode.pass_1: tnode;
   var
     msgsendname: string;
     newparas,
-    lastpara: tcallparanode;
+    para: tcallparanode;
     block: tblocknode;
     statements: tstatementnode;
     temp: ttempcreatenode;
     objcsupertype: tdef;
     field: tfieldvarsym;
+    selfpara,
+    msgselpara: tcallparanode;
   begin
     { pass1 of left has already run, see constructor }
 
@@ -228,12 +230,22 @@ function tobjcmessagesendnode.pass_1: tnode;
       msgsendname:='OBJC_MSGSENDSUPER';
 
     newparas:=tcallparanode(tcallnode(left).left);
-    { parameters are chained from right to left, and we have to insert the two
-      first parameters (self and selector) -> walk to the end of the chain
-    }
-    lastpara:=newparas;
-    while assigned(lastpara.right) do
-      lastpara:=tcallparanode(lastpara.right);
+    { Find the self and msgsel parameters.  }
+    para:=newparas;
+    selfpara:=nil;
+    msgselpara:=nil;
+    while assigned(para) do
+      begin
+        if (vo_is_self in para.parasym.varoptions) then
+          selfpara:=para
+        else if (vo_is_msgsel in para.parasym.varoptions) then
+          msgselpara:=para;
+        para:=tcallparanode(para.right);
+      end;
+    if not assigned(selfpara) then
+      internalerror(2009051801);
+    if not assigned(msgselpara) then
+      internalerror(2009051802);
     { Handle self }
     { 1) If we're calling a class method, use a class ref.  }
     if (po_classmethod in tcallnode(left).procdefinition.procoptions) and
@@ -283,12 +295,15 @@ function tobjcmessagesendnode.pass_1: tnode;
          tcallnode(left).methodpointer:=block;
          typecheckpass(block);
       end;
-    lastpara.right:=ccallparanode.create(tcallnode(left).methodpointer,nil);
-    { insert selector }
-    lastpara.right:=ccallparanode.create(
+    { replace self parameter }
+    selfpara.left.free;
+    selfpara.left:=tcallnode(left).methodpointer;
+    { replace selector parameter }
+    msgselpara.left.Free;
+    msgselpara.left:=
       cobjcselectornode.create(
-        cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^)),
-     lastpara.right);
+       cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^)
+      );
     { parameters are reused -> make sure they don't get freed }
     tcallnode(left).left:=nil;
     { methodpointer is also reused }