Browse Source

Decrease amount of code duplication regarding handling of safecall and record constructors.

paramgr.pas, tparamanager:
    + add new method "handle_common_ret_in_param"
    * extract common code (safecall + record constructor handling) from "ret_in_param" to "handle_common_ret_in_param" and call the latter in "ret_in_param"
[aarch64,arm,avr,i386,x86_64]/cpupara.pas, tCPUparamanager.ret_in_param:
    * call "handle_common_ret_in_param" instead of implementing the same check again and again
ncgcal.pas, tcgcallnode.handle_return_value:
    * move the check for (record) constructors to "tparamanager.handle_common_ret_in_param"

git-svn-id: trunk@23520 -
svenbarth 12 years ago
parent
commit
7bad1763b8

+ 2 - 9
compiler/aarch64/cpupara.pas

@@ -201,15 +201,8 @@ unit cpupara;
         sym: tsym;
         fpufield: boolean;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           recorddef:
             begin

+ 2 - 9
compiler/arm/cpupara.pas

@@ -207,15 +207,8 @@ unit cpupara;
         sym: tsym;
         fpufield: boolean;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           recorddef:
             begin

+ 2 - 9
compiler/avr/cpupara.pas

@@ -182,15 +182,8 @@ unit cpupara;
 
     function tavrparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           recorddef:
             { this is how gcc 4.0.4 on linux seems to do it, it doesn't look like being

+ 2 - 9
compiler/i386/cpupara.pas

@@ -96,15 +96,8 @@ unit cpupara;
       var
         size: longint;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case target_info.system of
           system_i386_win32 :
             begin

+ 1 - 2
compiler/ncgcal.pas

@@ -379,8 +379,7 @@ implementation
       begin
         { Check that the return location is set when the result is passed in
           a parameter }
-        if ((procdefinition.proctypeoption<>potype_constructor)or is_record(resultdef)) and
-           paramanager.ret_in_param(resultdef,procdefinition) then
+        if paramanager.ret_in_param(resultdef,procdefinition) then
           begin
             { self.location is set near the end of secondcallparan so it
               refers to the implicit result parameter }

+ 27 - 9
compiler/paramgr.pas

@@ -144,6 +144,11 @@ unit paramgr;
           { common part of get_funcretloc; returns true if retloc is completely
             initialized afterwards }
           function set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean;
+          { common part of ret_in_param; is called by ret_in_param at the
+            beginning and every tparamanager descendant can decide to call it
+            itself as well; parameter retinparam is only valid if function
+            returns true }
+          function handle_common_ret_in_param(def:tdef;pd:tabstractprocdef;out retinparam:boolean):boolean;
        end;
 
 
@@ -168,15 +173,8 @@ implementation
     { true if uses a parameter as return value }
     function tparamanager.ret_in_param(def:tdef;pd:tabstractprocdef):boolean;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+         if handle_common_ret_in_param(def,pd,result) then
+           exit;
          ret_in_param:=((def.typ=arraydef) and not(is_dynamic_array(def))) or
            (def.typ=recorddef) or
            (def.typ=stringdef) or
@@ -566,6 +564,26 @@ implementation
         result:=false;
       end;
 
+    function tparamanager.handle_common_ret_in_param(def: tdef;
+      pd: tabstractprocdef; out retinparam: boolean): boolean;
+      begin
+        { this must be system independent safecall and record constructor result
+          is always return in param }
+        if (tf_safecall_exceptions in target_info.flags) and
+           (pd.proccalloption=pocall_safecall) or
+           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
+          begin
+            retinparam:=true;
+            exit(true);
+          end;
+        if pd.proctypeoption=potype_constructor then
+          begin
+            retinparam:=false;
+            exit(true);
+          end;
+        result:=false;
+      end;
+
 initialization
   ;
 finalization

+ 2 - 9
compiler/x86_64/cpupara.pas

@@ -623,15 +623,8 @@ unit cpupara;
         classes: tx64paraclasses;
         numclasses: longint;
       begin
-        { this must be system independent safecall and record constructor result
-          is always return in param }
-        if (tf_safecall_exceptions in target_info.flags) and
-           (pd.proccalloption=pocall_safecall) or
-           ((pd.proctypeoption=potype_constructor)and is_record(def)) then
-          begin
-            result:=true;
-            exit;
-          end;
+        if handle_common_ret_in_param(def,pd,result) then
+          exit;
         case def.typ of
           { for records it depends on their contents and size }
           recorddef,