Prechádzať zdrojové kódy

More consequent writing of Rtti. Part of code related to recorddef moved from recorddef_rtti to write_child_data_rtti(). When typeinfo is used in code init Rtti is a child of the full Rtti. Commit also contains correction for code commited for mantis #31249 (r35376) and mantis #31305 (r35377) for objects. Before was impossible to compile code with usage of typeinfo() function for object without managed fields ("Undefined symbol" error).

+ Test attached

git-svn-id: trunk@35403 -
maciej-izak 8 rokov pred
rodič
commit
1d301b6dbe
3 zmenil súbory, kde vykonal 44 pridanie a 20 odobranie
  1. 1 0
      .gitattributes
  2. 26 20
      compiler/ncgrtti.pas
  3. 17 0
      tests/tbs/tb0626.pp

+ 1 - 0
.gitattributes

@@ -11093,6 +11093,7 @@ tests/tbs/tb0622.pp svneol=native#text/plain
 tests/tbs/tb0623.pp svneol=native#text/pascal
 tests/tbs/tb0624.pp svneol=native#text/pascal
 tests/tbs/tb0625.pp svneol=native#text/pascal
+tests/tbs/tb0626.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tb610.pp svneol=native#text/pascal
 tests/tbs/tb613.pp svneol=native#text/plain

+ 26 - 20
compiler/ncgrtti.pas

@@ -1139,25 +1139,13 @@ implementation
            if (rt=initrtti) then
              tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype)
            else
-             begin
-               { point to more optimal init table }
-               include(def.defstates,ds_init_table_used);
-               { we use a direct reference as the init RTTI is always in the same
-                 unit as the full RTTI }
-               tcb.emit_tai(Tai_const.Create_sym(get_rtti_label(def,initrtti,false)),voidpointertype);
-             end;
+             { we use a direct reference as the init RTTI is always in the same
+               unit as the full RTTI }
+             tcb.emit_tai(Tai_const.Create_sym(get_rtti_label(def,initrtti,false)),voidpointertype);
 
            tcb.emit_ord_const(def.size,u32inttype);
-
            fields_write_rtti_data(tcb,def,rt);
            tcb.end_anonymous_record;
-
-           { guarantee initrtti for any record for fpc_initialize, fpc_finalize }
-           if (rt=fullrtti) and
-               (ds_init_table_used in def.defstates) and
-               not (ds_init_table_written in def.defstates)
-               then
-             write_rtti(def, initrtti);
         end;
 
 
@@ -1736,7 +1724,16 @@ implementation
               write_rtti(tarraydef(def).elementdef,rt);
             end;
           recorddef :
-            fields_write_rtti(trecorddef(def).symtable,rt);
+            begin
+              { guarantee initrtti for any record for RTTI purposes 
+                also for fpc_initialize, fpc_finalize }
+              if (rt=fullrtti) then
+                begin
+                  include(def.defstates,ds_init_table_used);
+                  write_rtti(def, initrtti);
+                end;
+              fields_write_rtti(trecorddef(def).symtable,rt);
+            end;
           objectdef :
             begin
               if assigned(tobjectdef(def).childof) then
@@ -1746,10 +1743,19 @@ implementation
               else
                 published_write_rtti(tobjectdef(def).symtable,rt);
 
-              if (rt=fullrtti)
-                  and (is_interface(def) or is_dispinterface(def))
-                  and (oo_can_have_published in tobjectdef(def).objectoptions) then
-                methods_write_rtti(tobjectdef(def).symtable,rt,[vis_published],true);
+              if (rt=fullrtti) then
+                begin
+                  { guarantee initrtti for any object for RTTI purposes 
+                    also for fpc_initialize, fpc_finalize }
+                  if (tobjectdef(def).objecttype=odt_object) then
+                    begin
+                      include(def.defstates,ds_init_table_used);
+                      write_rtti(def,initrtti);
+                    end;
+                  if (is_interface(def) or is_dispinterface(def))
+                      and (oo_can_have_published in tobjectdef(def).objectoptions) then
+                    methods_write_rtti(tobjectdef(def).symtable,rt,[vis_published],true);
+                end;
             end;
           classrefdef,
           pointerdef:

+ 17 - 0
tests/tbs/tb0626.pp

@@ -0,0 +1,17 @@
+{ %norun }
+
+program tb0626;
+
+{$MODE OBJFPC}
+
+type
+  TNonManagedObj = object
+    d: double;
+  end;
+
+var
+  p: Pointer;
+begin
+  p := TypeInfo(TNonManagedObj);
+end.
+