Просмотр исходного кода

+ Determine early (before pass 2) whether managed parameters/locals/temps will cause the procedure to reference RTTI labels and, therefore, need GOT.
+ trttinode also sets pi_needs_got flag.

git-svn-id: trunk@24767 -

sergei 12 лет назад
Родитель
Сommit
4e873d0561
4 измененных файлов с 40 добавлено и 4 удалено
  1. 16 0
      compiler/defutil.pas
  2. 4 0
      compiler/nbas.pas
  3. 3 0
      compiler/nld.pas
  4. 17 4
      compiler/psub.pas

+ 16 - 0
compiler/defutil.pas

@@ -110,6 +110,9 @@ interface
     {# Returns whether def is reference counted }
     function is_managed_type(def: tdef) : boolean;{$ifdef USEINLINE}inline;{$endif}
 
+    { # Returns whether def is needs to load RTTI for reference counting }
+    function is_rtti_managed_type(def: tdef) : boolean;
+
 {    function is_in_limit_value(val_from:TConstExprInt;def_from,def_to : tdef) : boolean;}
 
 {*****************************************************************************
@@ -623,6 +626,19 @@ implementation
       end;
 
 
+    function is_rtti_managed_type(def: tdef): boolean;
+      begin
+        result:=def.needs_inittable and not (
+          is_interfacecom_or_dispinterface(def) or
+          (def.typ=variantdef) or
+          (
+            (def.typ=stringdef) and
+            (tstringdef(def).stringtype in [st_ansistring,st_widestring,st_unicodestring])
+          )
+        );
+      end;
+
+
     { true, if p points to an open array def }
     function is_open_string(p : tdef) : boolean;
       begin

+ 4 - 0
compiler/nbas.pas

@@ -914,6 +914,10 @@ implementation
         expectloc:=LOC_VOID;
         if (tempinfo^.typedef.needs_inittable) then
           include(current_procinfo.flags,pi_needs_implicit_finally);
+        if (cs_create_pic in current_settings.moduleswitches) and
+           (tf_pic_uses_got in target_info.flags) and
+           is_rtti_managed_type(tempinfo^.typedef) then
+          include(current_procinfo.flags,pi_needs_got);
         if assigned(tempinfo^.withnode) then
           firstpass(tempinfo^.withnode);
         if assigned(tempinfo^.tempinitcode) then

+ 3 - 0
compiler/nld.pas

@@ -1331,6 +1331,9 @@ implementation
       begin
         result:=nil;
         expectloc:=LOC_CREFERENCE;
+        if (cs_create_pic in current_settings.moduleswitches) and
+           (tf_pic_uses_got in target_info.flags) then
+          include(current_procinfo.flags,pi_needs_got);
       end;
 
 

+ 17 - 4
compiler/psub.pas

@@ -257,9 +257,16 @@ implementation
 
     procedure check_finalize_paras(p:TObject;arg:pointer);
       begin
-        if (tsym(p).typ=paravarsym) and
-           tparavarsym(p).needs_finalization then
-          include(current_procinfo.flags,pi_needs_implicit_finally);
+        if (tsym(p).typ=paravarsym) then
+          begin
+            if tparavarsym(p).needs_finalization then
+              include(current_procinfo.flags,pi_needs_implicit_finally);
+            if (tparavarsym(p).varspez in [vs_value,vs_out]) and
+               (cs_create_pic in current_settings.moduleswitches) and
+               (tf_pic_uses_got in target_info.flags) and
+               is_rtti_managed_type(tparavarsym(p).vardef) then
+              include(current_procinfo.flags,pi_needs_got);
+          end;
       end;
 
 
@@ -270,7 +277,13 @@ implementation
         if (tsym(p).typ=localvarsym) and
            (tlocalvarsym(p).refs>0) and
            is_managed_type(tlocalvarsym(p).vardef) then
-          include(current_procinfo.flags,pi_needs_implicit_finally);
+          begin
+            include(current_procinfo.flags,pi_needs_implicit_finally);
+            if is_rtti_managed_type(tlocalvarsym(p).vardef) and
+              (cs_create_pic in current_settings.moduleswitches) and
+              (tf_pic_uses_got in target_info.flags) then
+              include(current_procinfo.flags,pi_needs_got);
+          end;
       end;