Ver código fonte

Merge RTTI changes from packages branch (including adjustments that were required due to changes in trunk since then). These changes favor source backwards compatibility in contrast to Delphi compatibility. Binary compatiblity is however drastically broken due to the indirect references that are platform independant!

Merged revision(s) 28239-28289 from branches/svenbarth/packages:
Provide the possiblity to switch between the direct and indirect RTTI symbols.

ncgrtti.pas, TRTTIWriter:
  + get_rtti_label, get_rtti_label_ord2str & get_rtti_label_str2ord: add new "indirect" parameter and pass that along to rtti_mangledname
hlcgobj.pas, thlcgobj:
  * g_incrrefcount, g_initialize, g_finalize, g_array_rtti_helper: for now pass along False to get_rtti_label()
ncgvmt.pas, TVMTWriter:
  * writevmt: for now pass along False to get_rtti_label()
ncgld.pas, tcgrttinode:
  * pass_generate_code: for now pass along False to the get_rtti_label*() methods
........
Provide possibility to select between using a direct and an indirect RTTI reference. This way the references can be changed for selected cases.

ncgrtti, TRTTIWriter:
  * ref_rtti: new "indirect" parameter that's relayed to rtti_mangledname()
  * write_rtti_reference: new "indirect" paramater that's relayed to ref_rtti()
........
Switch properties to use the indirect type information without breaking backwards compatiblity. :)

compiler/ncgrtti.pas, TRTTIWriter:
  * published_properties_write_rtti_data: use the indirect reference, not the direct one
rtl/objpas/typinfo.pp:
  * to allow compilation with both 2.6.x and 2.7.1 and too avoid too many ifdefs at least in the declarations we define a macro TypeInfoPtr which is either PTypeInfo (2.6.x) or PPTypeInfo (2.7.1 and newer)
  * TPropInfo: rename PropType to PropTypeRef and change type to TypeInfoPtr
  + TPropInfo: add a new property PropType which returns a PTypeInfo out of the PropTypeRef depending on the compiler version
........
Switch further simple types (sets, enums, class references, pointers) to indirect type information (again without breaking backwards compatibility).

compiler/ncgrtti.pas, TRTTIWriter.write_rtti_data:
  * enumdef_rtti, setdef_rtti, classrefdef_rtti & pointerdef_rtti: write an indirect RTTI reference

rtl/objpas/typinfo.pp, TTypeData:
  * rename BaseType to BaseTypeRef, CompType to CompTypeRef, InstanceType to InstanceTypeRef and RefType to RefTypeRef and change their type to TypeInfoPtr
  + add properties BaseType, CompType, InstanceType & RefType which return a PTypeInfo out of the corresponding *Ref field depending on the compiler version
........
Switch class and interface parent as well as extended type to indirect type information

compiler/ncgrtti.pas, TRTTIWriter:
  * write_rtti_data.objectdef_rtti.objectdef_rtti_class_full: use indirect reference for class parent and extended type
  * write_rtti_data.objectdef_rtti.objectdef_rtti_interface_full: use indirect reference for interface parent

rtl/objpas/typinfo.pp, TTypeData:
  + add new method DerefTypeInfoPtr which returns Nil if the indirect reference is Nil and otherwise returns the dereferences indirect reference (for 2.6.x the direct reference is returned as is)
  * rename ParentInfo to ParentInfoRef, HelperParent to HelperParentRef, ExtendedInfo to ExtendedInfoRef, IntfParent ot IntfParentRef and RawIntfParent to RawIntfParentRef and change their type to TypeInfoPtr
  + introduce ParentInfo, HelperParent, ExtendedInfo, IntfParent and RawIntfParent properties that return a PTypeInfo and use the new DerefTypeInfoPtr to return the correct type info value
  * change the other newly introduced properties of TTypeData to use DerefTypeInfoPtr as well to be on the safe side
........
Switch record/object fields to indirect type information references.

compiler/ncgrtti.pas, TRTTIWriter.fields_write_rtti_data:
  * use the indirect reference for the object parent type
  * use the indirect reference for the field type

rtl/inc/rtti.inc:
  * TRecordElement: change TypeInfo to PPointer for 2.7.1 and newer
  * RecordRTTI: correctly dereference the element type for 2.7.1 and newer
  * fpc_copy: correctly reference the element type for 2.7.1 and newer
........
Switch static arrays to indirect RTTI reference.

compiler/ncgrtti.pas, TRTTIWriter.write_rtti_data:
  * arraydef_rtti: write the dimension types and the final field type as indirect references

rtl/inc/rtti.inc:
  * TArrayInfo: switch ElInfo to PPointer for 2.7.1+
  * ArrayRTTI & fpc_copy: correctly dereference ElInfo for 2.7.1+
rtl/objpas/typinfo.pp, TArrayTypeData:
  * switch ElType and Dims to PPTypeInfo; no backwards compatibility needed here as TArrayTypeData was added in 2.7.1 only

tests/test/trtti8.pp: fix test
........
Switch dynamic arrays to indirect RTTI references.

compiler/ncgrtti.pas, TRTTIWriter.write_rtti_data.arraydef_rtti:
  * write indirect references for the two element entries

rtl/inc/dynarr.inc:
  * tdynarraytypedata: change elType2 to PPointer for 2.7.1+
  * fpc_dynarray_clear, fpc_dynarray_setlength & fpc_dynarray_copy: correctly dereference elType2 for 2.7.1+
rtl/objpas/typinfo.pp, TTypeData:
  * rename elType and elType2 to elTypeRef and elType2Ref respectively and change type to TypeInfoPtr
  * add properties elType and elType2 which return PTypeInfo by dereferencing elTypeRef and elType2Ref respecively correctly
  * remove a few stray "inline" directives in the implementation
........
Switch procedure parameters and result type to indirect RTTI references.

compiler/ncgrtti.pas, TRTTIWriter.write_rtti_data.procvardef_rtti:
  * write_procedure_param: use indirect RTTI reference
  * write result info for both methods and procvars as indirect RTTI reference
  * write parameters for procvars as indirect RTTI reference

rtl/objpas/typinfo.pp:
  * TProcedureParam: change type of ParamType to PPTypeInfo (no backwards compatiblity needed here; was added for 2.7.1)
  * TProcedureSignature: change type of RseultType to PPTypeInfo (no backwards compatibility needed here; was added for 2.7.1)
  * TTypeData: remark in the comments of tkMethod that ResultTypeRef and ParamTypeRefs are of type PPTypeInfo and not PTypeInfo

tests/test/trtti9.pp: 
  * fix test
........
Remove no longer needed "indirect" parameter for TRTTIWriter methods.

ncgrtti.pas, TRTTIWriter:
  - ref_rtti & write_rtti_reference: remove "indirect" parameter
  * ref_rtti: call rtti_mangledname with "indirect" always set to "true"
  - remove "true" parameter on callsites of write_rtti_reference & ref_rtti
........

git-svn-id: trunk@33944 -
svenbarth 9 anos atrás
pai
commit
345d83c3e3

+ 4 - 4
compiler/hlcgobj.pas

@@ -3280,7 +3280,7 @@ implementation
           paramanager.getintparaloc(list,pd,2,cgpara2);
           if is_open_array(t) then
             InternalError(201103054);
-          reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
+          reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti,false),0,sizeof(pint));
           if pd.is_pushleftright then
             begin
               a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
@@ -3328,7 +3328,7 @@ implementation
             pd:=search_system_proc('fpc_initialize');
             paramanager.getintparaloc(list,pd,1,cgpara1);
             paramanager.getintparaloc(list,pd,2,cgpara2);
-            reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
+            reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti,false),0,sizeof(pint));
             if pd.is_pushleftright then
               begin
                 a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
@@ -3378,7 +3378,7 @@ implementation
             pd:=search_system_proc('fpc_finalize');
           paramanager.getintparaloc(list,pd,1,cgpara1);
           paramanager.getintparaloc(list,pd,2,cgpara2);
-          reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
+          reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti,false),0,sizeof(pint));
           if pd.is_pushleftright then
             begin
               a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
@@ -3420,7 +3420,7 @@ implementation
       paramanager.getintparaloc(list,pd,2,cgpara2);
       paramanager.getintparaloc(list,pd,3,cgpara3);
 
-      reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
+      reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti,false),0,sizeof(pint));
       { if calling convention is left to right, push parameters 1 and 2 }
       if pd.is_pushleftright then
         begin

+ 3 - 3
compiler/ncgld.pas

@@ -1451,11 +1451,11 @@ implementation
         location_reset_ref(location,LOC_CREFERENCE,OS_NO,sizeof(pint));
         case rttidatatype of
           rdt_normal:
-            location.reference.symbol:=RTTIWriter.get_rtti_label(rttidef,rttitype);
+            location.reference.symbol:=RTTIWriter.get_rtti_label(rttidef,rttitype,false);
           rdt_ord2str:
-            location.reference.symbol:=RTTIWriter.get_rtti_label_ord2str(rttidef,rttitype);
+            location.reference.symbol:=RTTIWriter.get_rtti_label_ord2str(rttidef,rttitype,false);
           rdt_str2ord:
-            location.reference.symbol:=RTTIWriter.get_rtti_label_str2ord(rttidef,rttitype);
+            location.reference.symbol:=RTTIWriter.get_rtti_label_str2ord(rttidef,rttitype,false);
         end;
       end;
 

+ 11 - 11
compiler/ncgrtti.pas

@@ -59,9 +59,9 @@ interface
       public
         constructor create;
         procedure write_rtti(def:tdef;rt:trttitype);
-        function  get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
-        function  get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
-        function  get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
+        function  get_rtti_label(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
+        function  get_rtti_label_ord2str(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
+        function  get_rtti_label_str2ord(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
       end;
 
     { generate RTTI and init tables }
@@ -791,7 +791,7 @@ implementation
                  begin
                    curdef:=tarraydef(finaldef);
                    finaldef:=curdef.elementdef;
-                   { Dims[i] PTypeInfo }
+                   { Dims[i] PPTypeInfo }
                    write_rtti_reference(tcb,curdef.rangedef,rt);
                  end;
              end
@@ -1531,7 +1531,7 @@ implementation
 
     function TRTTIWriter.ref_rtti(def:tdef;rt:trttitype):tasmsymbol;
       begin
-        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt),AT_DATA);
+        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt),AT_DATA,true);
         if (cs_create_pic in current_settings.moduleswitches) and
            assigned(current_procinfo) then
           include(current_procinfo.flags,pi_needs_got);
@@ -1598,25 +1598,25 @@ implementation
       end;
 
 
-    function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
+    function TRTTIWriter.get_rtti_label(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
       begin
-        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt),AT_DATA);
+        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt),AT_DATA,indirect);
         if (cs_create_pic in current_settings.moduleswitches) and
            assigned(current_procinfo) then
           include(current_procinfo.flags,pi_needs_got);
       end;
 
-    function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
+    function TRTTIWriter.get_rtti_label_ord2str(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
       begin
-        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_o2s',AT_DATA);
+        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_o2s',AT_DATA,indirect);
         if (cs_create_pic in current_settings.moduleswitches) and
            assigned(current_procinfo) then
           include(current_procinfo.flags,pi_needs_got);
       end;
 
-    function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
+    function TRTTIWriter.get_rtti_label_str2ord(def:tdef;rt:trttitype;indirect:boolean):tasmsymbol;
       begin
-        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_s2o',AT_DATA);
+        result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_s2o',AT_DATA,indirect);
         if (cs_create_pic in current_settings.moduleswitches) and
            assigned(current_procinfo) then
           include(current_procinfo.flags,pi_needs_got);

+ 2 - 2
compiler/ncgvmt.pas

@@ -1170,10 +1170,10 @@ implementation
             else
               tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype);
             { pointer to type info of published section }
-            tcb.emit_tai(Tai_const.Create_sym(RTTIWriter.get_rtti_label(_class,fullrtti)),voidpointertype);
+            tcb.emit_tai(Tai_const.Create_sym(RTTIWriter.get_rtti_label(_class,fullrtti,false)),voidpointertype);
             { inittable for con-/destruction }
             if _class.members_need_inittable then
-              tcb.emit_tai(Tai_const.Create_sym(RTTIWriter.get_rtti_label(_class,initrtti)),voidpointertype)
+              tcb.emit_tai(Tai_const.Create_sym(RTTIWriter.get_rtti_label(_class,initrtti,false)),voidpointertype)
             else
               tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype);
             { auto table }

+ 27 - 1
rtl/inc/dynarr.inc

@@ -31,9 +31,17 @@ type
 {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
    record
      elSize : SizeUInt;
+     {$ifdef VER3_0}
      elType2 : Pointer;
+     {$else}
+     elType2 : PPointer;
+     {$endif}
      varType : Longint;
+     {$ifdef VER3_0}
      elType : Pointer;
+     {$else}
+     elType : PPointer;
+     {$endif}
    end;
 
 procedure fpc_dynarray_rangecheck(p : pointer;i : tdynarrayindex);[Public,Alias:'FPC_DYNARRAY_RANGECHECK']; compilerproc;
@@ -75,7 +83,7 @@ procedure fpc_dynarray_clear(var p : pointer;ti : pointer); [Public,Alias:'FPC_D
       begin
         ti:=aligntoptr(ti+2+PByte(ti)[1]);
         if assigned(pdynarraytypedata(ti)^.elType) then
-          int_finalizearray(p,pdynarraytypedata(ti)^.elType,realp^.high+1);
+          int_finalizearray(p,pdynarraytypedata(ti)^.elType{$ifndef VER3_0}^{$endif},realp^.high+1);
         freemem(realp);
       end;
     p:=nil;
@@ -141,9 +149,20 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
      ti:=aligntoptr(Pointer(pti)+2+PByte(pti)[1]);
 
      elesize:=pdynarraytypedata(ti)^.elSize;
+     {$ifdef VER3_0}
      eletype:=pdynarraytypedata(ti)^.elType2;
+     {$else}
+     eletype:=pdynarraytypedata(ti)^.elType2^;
+     {$endif}
      { only set if type needs finalization }
+     {$ifdef VER3_0}
      eletypemngd:=pdynarraytypedata(ti)^.elType;
+     {$else}
+     if assigned(pdynarraytypedata(ti)^.elType) then
+       eletypemngd:=pdynarraytypedata(ti)^.elType^
+     else
+       eletypemngd:=nil;
+     {$endif}
 
      { determine new memory size }
      size:=elesize*dims[0]+sizeof(tdynarray);
@@ -293,7 +312,14 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
 
      elesize:=pdynarraytypedata(ti)^.elSize;
      { only set if type needs finalization }
+     {$ifdef VER3_0}
      eletype:=pdynarraytypedata(ti)^.elType;
+     {$else}
+     if assigned(pdynarraytypedata(ti)^.elType) then
+       eletype:=pdynarraytypedata(ti)^.elType^
+     else
+       eletype:=nil;
+     {$endif}
 
      { create new array }
      size:=elesize*count;

+ 5 - 0
rtl/inc/dynarrh.inc

@@ -20,12 +20,17 @@ type
   pdynarrayindex = ^tdynarrayindex;
 
   pdynarraytypeinfo = ^tdynarraytypeinfo;
+  ppdynarraytypeinfo = ^pdynarraytypeinfo;
   tdynarraytypeinfo = packed record
     kind : byte;
     namelen : byte;
     { here the chars follow, we've to skip them }
     elesize : sizeint;
+    {$ifdef VER3_0}
     eletype : pdynarraytypeinfo;
+    {$else}
+    eletype : ppdynarraytypeinfo;
+    {$endif}
     vartype : longint;
   end;
   

+ 12 - 4
rtl/inc/rtti.inc

@@ -30,7 +30,11 @@ type
   packed
 {$endif USE_PACKED}
   record
+    {$ifdef VER3_0}
     TypeInfo: Pointer;
+    {$else}
+    TypeInfo: PPointer;
+    {$endif}
     {$ifdef VER2_6}
     Offset: Longint;
     {$else}
@@ -57,7 +61,11 @@ type
   record
     Size: SizeInt;
     ElCount: SizeInt;
+{$ifdef VER3_0}
     ElInfo: Pointer;
+{$else}
+    ElInfo: PPointer;
+{$endif}
     DimCount: Byte;
     Dims:array[0..255] of Pointer;
   end;
@@ -109,7 +117,7 @@ begin
   { Process elements }
   for i:=1 to count Do
     begin
-      rttiproc(Data+PRecordElement(typeInfo)^.Offset,PRecordElement(typeInfo)^.TypeInfo);
+      rttiproc(Data+PRecordElement(typeInfo)^.Offset,PRecordElement(typeInfo)^.TypeInfo{$ifndef VER3_0}^{$endif});
       Inc(PRecordElement(typeInfo));
     end;
 end;
@@ -138,7 +146,7 @@ begin
   if Count = 0 then
     Exit;
   ElSize:=PArrayInfo(typeInfo)^.Size div Count;
-  Info:=PArrayInfo(typeInfo)^.ElInfo;
+  Info:=PArrayInfo(typeInfo)^.ElInfo{$ifndef VER3_0}^{$endif};
   { Process elements }
   for I:=0 to Count-1 do
     rttiproc(Data+(I*ElSize),Info);
@@ -287,7 +295,7 @@ begin
         { no elements to process => exit }
         if Count = 0 then
           Exit;
-        Info:=PArrayInfo(Temp)^.ElInfo;
+        Info:=PArrayInfo(Temp)^.ElInfo{$ifndef VER3_0}^{$endif};
         copiedsize:=Result div Count;
         Offset:=0;
         { Process elements }
@@ -312,7 +320,7 @@ begin
         { Process elements with rtti }
         for i:=1 to count Do
           begin
-            Info:=PRecordElement(Temp)^.TypeInfo;
+            Info:=PRecordElement(Temp)^.TypeInfo{$ifndef VER3_0}^{$endif};
             Offset:=PRecordElement(Temp)^.Offset;
             Inc(PRecordElement(Temp));
             if Offset>expectedoffset then

+ 199 - 19
rtl/objpas/typinfo.pp

@@ -23,6 +23,7 @@ unit typinfo;
 {$MODE objfpc}
 {$MODESWITCH AdvancedRecords}
 {$inline on}
+{$macro on}
 {$h+}
 
   uses SysUtils;
@@ -113,6 +114,14 @@ unit typinfo;
       PTypeInfo = ^TTypeInfo;
       PPTypeInfo = ^PTypeInfo;
 
+{ Note: these are only for backwards compatibility. New type references should
+        only use PPTypeInfo directly! }
+{$ifdef ver3_0}
+{$define TypeInfoPtr := PTypeInfo}
+{$else}
+{$define TypeInfoPtr := PPTypeInfo}
+{$endif}
+
 {$PACKRECORDS C}
       // members of TTypeData
       TArrayTypeData =
@@ -120,11 +129,18 @@ unit typinfo;
       packed
 {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
       record
+      private
+        function GetElType: PTypeInfo; inline;
+        function GetDims(aIndex: Byte): PTypeInfo; inline;
+      public
+        property ElType: PTypeInfo read GetElType;
+        property Dims[Index: Byte]: PTypeInfo read GetDims;
+      public
         Size: SizeInt;
         ElCount: SizeInt;
-        ElType: PTypeInfo;
+        ElTypeRef: TypeInfoPtr;
         DimCount: Byte;
-        Dims: array[0..255] of PTypeInfo;
+        DimsRef: array[0..255] of TypeInfoPtr;
       end;
 
       PManagedField = ^TManagedField;
@@ -133,7 +149,12 @@ unit typinfo;
       packed
       {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
       record
-        TypeRef: PTypeInfo;
+      private
+        function GetTypeRef: PTypeInfo; inline;
+      public
+        property TypeRef: PTypeInfo read GetTypeRef;
+      public
+        TypeRefRef: TypeInfoPtr;
         FldOffset: SizeInt;
       end;
 
@@ -143,8 +164,13 @@ unit typinfo;
       packed
       {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
       record
+      private
+        function GetParamType: PTypeInfo; inline;
+      public
+        property ParamType: PTypeInfo read GetParamType;
+      public
         Flags: Byte;
-        ParamType: PTypeInfo;
+        ParamTypeRef: TypeInfoPtr;
         Name: ShortString;
       end;
 
@@ -153,9 +179,14 @@ unit typinfo;
       packed
       {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
       record
+      private
+        function GetResultType: PTypeInfo; inline;
+      public
+        property ResultType: PTypeInfo read GetResultType;
+      public
         Flags: Byte;
         CC: TCallConv;
-        ResultType: PTypeInfo;
+        ResultTypeRef: TypeInfoPtr;
         ParamCount: Byte;
         {Params: array[0..ParamCount - 1] of TProcedureParam;}
         function GetParam(ParamIndex: Integer): PProcedureParam;
@@ -167,6 +198,40 @@ unit typinfo;
       packed
 {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
       record
+      private
+        function GetBaseType: PTypeInfo; inline;
+        function GetCompType: PTypeInfo; inline;
+        function GetParentInfo: PTypeInfo; inline;
+        function GetHelperParent: PTypeInfo; inline;
+        function GetExtendedInfo: PTypeInfo; inline;
+        function GetIntfParent: PTypeInfo; inline;
+        function GetRawIntfParent: PTypeInfo; inline;
+        function GetElType: PTypeInfo; inline;
+        function GetElType2: PTypeInfo; inline;
+        function GetInstanceType: PTypeInfo; inline;
+        function GetRefType: PTypeInfo; inline;
+      public
+        { tkEnumeration }
+        property BaseType: PTypeInfo read GetBaseType;
+        { tkSet }
+        property CompType: PTypeInfo read GetCompType;
+        { tkClass }
+        property ParentInfo: PTypeInfo read GetParentInfo;
+        { tkHelper }
+        property HelperParent: PTypeInfo read GetHelperParent;
+        property ExtendedInfo: PTypeInfo read GetExtendedInfo;
+        { tkInterface }
+        property IntfParent: PTypeInfo read GetIntfParent;
+        { tkInterfaceRaw }
+        property RawIntfParent: PTypeInfo read GetRawIntfParent;
+        { tkDynArray }
+        property ElType2: PTypeInfo read GetElType2;
+        property ElType: PTypeInfo read GetElType;
+        { tkClassRef }
+        property InstanceType: PTypeInfo read GetInstanceType;
+        { tkPointer }
+        property RefType: PTypeInfo read GetRefType;
+      public
          case TTypeKind of
             tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
               ();
@@ -180,12 +245,12 @@ unit typinfo;
                     case TTypeKind of
                       tkEnumeration:
                         (
-                        BaseType : PTypeInfo;
+                        BaseTypeRef : TypeInfoPtr;
                         NameList : ShortString;
                         {EnumUnitName: ShortString;})
                     );
                   tkSet:
-                    (CompType : PTypeInfo)
+                    (CompTypeRef : TypeInfoPtr)
               );
 {$ifndef FPUNONE}
             tkFloat:
@@ -195,7 +260,7 @@ unit typinfo;
               (MaxLength : Byte);
             tkClass:
               (ClassType : TClass;
-               ParentInfo : PTypeInfo;
+               ParentInfoRef : TypeInfoPtr;
                PropCount : SmallInt;
                UnitName : ShortString
                // here the properties follow as array of TPropInfo
@@ -207,8 +272,8 @@ unit typinfo;
                 {ManagedFields: array[1..ManagedFldCount] of TManagedField}
               );
             tkHelper:
-              (HelperParent : PTypeInfo;
-               ExtendedInfo : PTypeInfo;
+              (HelperParentRef : TypeInfoPtr;
+               ExtendedInfoRef : TypeInfoPtr;
                HelperProps : SmallInt;
                HelperUnit : ShortString
                // here the properties follow as array of TPropInfo
@@ -225,9 +290,9 @@ unit typinfo;
                   end;
               followed by
                   ResultType : ShortString     // for mkFunction, mkClassFunction only
-                  ResultTypeRef : PTypeInfo;  // for mkFunction, mkClassFunction only
+                  ResultTypeRef : PPTypeInfo;  // for mkFunction, mkClassFunction only
                   CC : TCallConv;
-                  ParamTypeRefs : array[1..ParamCount] of PTypeInfo;}
+                  ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
               );
             tkProcVar:
               (ProcSig: TProcedureSignature);
@@ -237,7 +302,7 @@ unit typinfo;
               (MinQWordValue, MaxQWordValue: QWord);
             tkInterface:
               (
-               IntfParent: PTypeInfo;
+               IntfParentRef: TypeInfoPtr;
                IntfFlags : TIntfFlagsBase;
                GUID: TGUID;
                IntfUnit: ShortString;
@@ -245,7 +310,7 @@ unit typinfo;
               );
             tkInterfaceRaw:
               (
-               RawIntfParent: PTypeInfo;
+               RawIntfParentRef: TypeInfoPtr;
                RawIntfFlags : TIntfFlagsBase;
                IID: TGUID;
                RawIntfUnit: ShortString;
@@ -257,15 +322,15 @@ unit typinfo;
             tkDynArray:
               (
               elSize     : PtrUInt;
-              elType2    : PTypeInfo;
+              elType2Ref : TypeInfoPtr;
               varType    : Longint;
-              elType     : PTypeInfo;
+              elTypeRef  : TypeInfoPtr;
               DynUnitName: ShortStringBase
               );
             tkClassRef:
-              (InstanceType: PTypeInfo);
+              (InstanceTypeRef: TypeInfoPtr);
             tkPointer:
-              (RefType: PTypeInfo);
+              (RefTypeRef: TypeInfoPtr);
       end;
 
       TPropData =
@@ -280,7 +345,10 @@ unit typinfo;
 
       PPropInfo = ^TPropInfo;
       TPropInfo = packed record
-        PropType : PTypeInfo;
+      private
+        function GetPropType: PTypeInfo; inline;
+      public
+        PropTypeRef : TypeInfoPtr;
         GetProc : CodePointer;
         SetProc : CodePointer;
         StoredProc : CodePointer;
@@ -296,6 +364,7 @@ unit typinfo;
         PropProcs : Byte;
 
         Name : ShortString;
+        property PropType: PTypeInfo read GetPropType;
       end;
 
       TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
@@ -452,6 +521,9 @@ Const
   OnGetVariantprop : TGetVariantProp = Nil;
   OnSetVariantprop : TSetVariantProp = Nil;
 
+{ for inlining }
+function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
+
 Implementation
 
 uses rtlconsts;
@@ -473,6 +545,19 @@ function aligntoptr(p : pointer) : pointer;inline;
    end;
 
 
+function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
+begin
+{$ifdef ver3_0}
+  Result := Info;
+{$else}
+  if not Assigned(Info) then
+    Result := Nil
+  else
+    Result := Info^;
+{$endif}
+end;
+
+
 Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
 
   Var PS : PShortString;
@@ -2068,8 +2153,39 @@ begin
   Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
 end;
 
+{ TProcedureParam }
+
+function TProcedureParam.GetParamType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(ParamTypeRef);
+end;
+
+{ TManagedField }
+
+function TManagedField.GetTypeRef: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(TypeRefRef);
+end;
+
+{ TArrayTypeData }
+
+function TArrayTypeData.GetElType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(ElTypeRef);
+end;
+
+function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(DimsRef[aIndex]);
+end;
+
 { TProcedureSignature }
 
+function TProcedureSignature.GetResultType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(ResultTypeRef);
+end;
+
 function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
 begin
   if (ParamIndex<0)or(ParamIndex>=ParamCount) then
@@ -2082,4 +2198,68 @@ begin
     end;
 end;
 
+{ TTypeData }
+
+function TTypeData.GetBaseType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(BaseTypeRef);
+end;
+
+function TTypeData.GetCompType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(CompTypeRef);
+end;
+
+function TTypeData.GetParentInfo: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(ParentInfoRef);
+end;
+
+function TTypeData.GetHelperParent: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(HelperParentRef);
+end;
+
+function TTypeData.GetExtendedInfo: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(ExtendedInfoRef);
+end;
+
+function TTypeData.GetIntfParent: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(IntfParentRef);
+end;
+
+function TTypeData.GetRawIntfParent: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(RawIntfParentRef);
+end;
+
+function TTypeData.GetElType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(elTypeRef);
+end;
+
+function TTypeData.GetElType2: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(elType2Ref);
+end;
+
+function TTypeData.GetInstanceType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(InstanceTypeRef);
+end;
+
+function TTypeData.GetRefType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(RefTypeRef);
+end;
+
+{ TPropInfo }
+
+function TPropInfo.GetPropType: PTypeInfo;
+begin
+  Result := DerefTypeInfoPtr(PropTypeRef);
+end;
+
 end.